ActivityManagerService.java revision 9f49df933f01a32d04bdf92d53c943065aa8ddf7
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.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.service.voice.IVoiceInteractionSession;
39import android.util.ArrayMap;
40
41import com.android.internal.R;
42import com.android.internal.annotations.GuardedBy;
43import com.android.internal.app.IAppOpsService;
44import com.android.internal.app.IVoiceInteractor;
45import com.android.internal.app.ProcessMap;
46import com.android.internal.app.ProcessStats;
47import com.android.internal.content.PackageMonitor;
48import com.android.internal.os.BackgroundThread;
49import com.android.internal.os.BatteryStatsImpl;
50import com.android.internal.os.ProcessCpuTracker;
51import com.android.internal.os.TransferPipe;
52import com.android.internal.os.Zygote;
53import com.android.internal.util.FastPrintWriter;
54import com.android.internal.util.FastXmlSerializer;
55import com.android.internal.util.MemInfoReader;
56import com.android.internal.util.Preconditions;
57import com.android.server.AppOpsService;
58import com.android.server.AttributeCache;
59import com.android.server.IntentResolver;
60import com.android.server.LocalServices;
61import com.android.server.ServiceThread;
62import com.android.server.SystemService;
63import com.android.server.SystemServiceManager;
64import com.android.server.Watchdog;
65import com.android.server.am.ActivityStack.ActivityState;
66import com.android.server.firewall.IntentFirewall;
67import com.android.server.pm.UserManagerService;
68import com.android.server.wm.AppTransition;
69import com.android.server.wm.WindowManagerService;
70import com.google.android.collect.Lists;
71import com.google.android.collect.Maps;
72
73import libcore.io.IoUtils;
74
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77import org.xmlpull.v1.XmlSerializer;
78
79import android.app.Activity;
80import android.app.ActivityManager;
81import android.app.ActivityManager.RunningTaskInfo;
82import android.app.ActivityManager.StackInfo;
83import android.app.ActivityManagerInternal;
84import android.app.ActivityManagerNative;
85import android.app.ActivityOptions;
86import android.app.ActivityThread;
87import android.app.AlertDialog;
88import android.app.AppGlobals;
89import android.app.ApplicationErrorReport;
90import android.app.Dialog;
91import android.app.IActivityController;
92import android.app.IApplicationThread;
93import android.app.IInstrumentationWatcher;
94import android.app.INotificationManager;
95import android.app.IProcessObserver;
96import android.app.IServiceConnection;
97import android.app.IStopUserCallback;
98import android.app.IUiAutomationConnection;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.backup.IBackupManager;
105import android.content.ActivityNotFoundException;
106import android.content.BroadcastReceiver;
107import android.content.ClipData;
108import android.content.ComponentCallbacks2;
109import android.content.ComponentName;
110import android.content.ContentProvider;
111import android.content.ContentResolver;
112import android.content.Context;
113import android.content.DialogInterface;
114import android.content.IContentProvider;
115import android.content.IIntentReceiver;
116import android.content.IIntentSender;
117import android.content.Intent;
118import android.content.IntentFilter;
119import android.content.IntentSender;
120import android.content.pm.ActivityInfo;
121import android.content.pm.ApplicationInfo;
122import android.content.pm.ConfigurationInfo;
123import android.content.pm.IPackageDataObserver;
124import android.content.pm.IPackageManager;
125import android.content.pm.InstrumentationInfo;
126import android.content.pm.PackageInfo;
127import android.content.pm.PackageManager;
128import android.content.pm.ParceledListSlice;
129import android.content.pm.UserInfo;
130import android.content.pm.PackageManager.NameNotFoundException;
131import android.content.pm.PathPermission;
132import android.content.pm.ProviderInfo;
133import android.content.pm.ResolveInfo;
134import android.content.pm.ServiceInfo;
135import android.content.res.CompatibilityInfo;
136import android.content.res.Configuration;
137import android.graphics.Bitmap;
138import android.net.Proxy;
139import android.net.ProxyProperties;
140import android.net.Uri;
141import android.os.Binder;
142import android.os.Build;
143import android.os.Bundle;
144import android.os.Debug;
145import android.os.DropBoxManager;
146import android.os.Environment;
147import android.os.FactoryTest;
148import android.os.FileObserver;
149import android.os.FileUtils;
150import android.os.Handler;
151import android.os.IBinder;
152import android.os.IPermissionController;
153import android.os.IRemoteCallback;
154import android.os.IUserManager;
155import android.os.Looper;
156import android.os.Message;
157import android.os.Parcel;
158import android.os.ParcelFileDescriptor;
159import android.os.Process;
160import android.os.RemoteCallbackList;
161import android.os.RemoteException;
162import android.os.SELinux;
163import android.os.ServiceManager;
164import android.os.StrictMode;
165import android.os.SystemClock;
166import android.os.SystemProperties;
167import android.os.UpdateLock;
168import android.os.UserHandle;
169import android.provider.Settings;
170import android.text.format.DateUtils;
171import android.text.format.Time;
172import android.util.AtomicFile;
173import android.util.EventLog;
174import android.util.Log;
175import android.util.Pair;
176import android.util.PrintWriterPrinter;
177import android.util.Slog;
178import android.util.SparseArray;
179import android.util.TimeUtils;
180import android.util.Xml;
181import android.view.Gravity;
182import android.view.LayoutInflater;
183import android.view.View;
184import android.view.WindowManager;
185
186import java.io.BufferedInputStream;
187import java.io.BufferedOutputStream;
188import java.io.DataInputStream;
189import java.io.DataOutputStream;
190import java.io.File;
191import java.io.FileDescriptor;
192import java.io.FileInputStream;
193import java.io.FileNotFoundException;
194import java.io.FileOutputStream;
195import java.io.IOException;
196import java.io.InputStreamReader;
197import java.io.PrintWriter;
198import java.io.StringWriter;
199import java.lang.ref.WeakReference;
200import java.util.ArrayList;
201import java.util.Arrays;
202import java.util.Collections;
203import java.util.Comparator;
204import java.util.HashMap;
205import java.util.HashSet;
206import java.util.Iterator;
207import java.util.List;
208import java.util.Locale;
209import java.util.Map;
210import java.util.Set;
211import java.util.concurrent.atomic.AtomicBoolean;
212import java.util.concurrent.atomic.AtomicLong;
213
214public final class ActivityManagerService extends ActivityManagerNative
215        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
216    private static final String USER_DATA_DIR = "/data/user/";
217    static final String TAG = "ActivityManager";
218    static final String TAG_MU = "ActivityManagerServiceMU";
219    static final boolean DEBUG = false;
220    static final boolean localLOGV = DEBUG;
221    static final boolean DEBUG_BACKUP = localLOGV || false;
222    static final boolean DEBUG_BROADCAST = localLOGV || false;
223    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
224    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_CLEANUP = localLOGV || false;
226    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
227    static final boolean DEBUG_FOCUS = false;
228    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
229    static final boolean DEBUG_MU = localLOGV || false;
230    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
231    static final boolean DEBUG_LRU = localLOGV || false;
232    static final boolean DEBUG_PAUSE = localLOGV || false;
233    static final boolean DEBUG_POWER = localLOGV || false;
234    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
235    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
236    static final boolean DEBUG_PROCESSES = localLOGV || false;
237    static final boolean DEBUG_PROVIDER = localLOGV || false;
238    static final boolean DEBUG_RESULTS = localLOGV || false;
239    static final boolean DEBUG_SERVICE = localLOGV || false;
240    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
241    static final boolean DEBUG_STACK = localLOGV || false;
242    static final boolean DEBUG_SWITCH = localLOGV || false;
243    static final boolean DEBUG_TASKS = localLOGV || false;
244    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
245    static final boolean DEBUG_TRANSITION = localLOGV || false;
246    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
247    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
248    static final boolean DEBUG_VISBILITY = localLOGV || false;
249    static final boolean DEBUG_PSS = localLOGV || false;
250    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
251    static final boolean VALIDATE_TOKENS = false;
252    static final boolean SHOW_ACTIVITY_START_TIME = true;
253
254    // Control over CPU and battery monitoring.
255    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
256    static final boolean MONITOR_CPU_USAGE = true;
257    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
258    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
259    static final boolean MONITOR_THREAD_CPU_USAGE = false;
260
261    // The flags that are set for all calls we make to the package manager.
262    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
263
264    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
265
266    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
267
268    // Maximum number of recent tasks that we can remember.
269    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
270
271    // Amount of time after a call to stopAppSwitches() during which we will
272    // prevent further untrusted switches from happening.
273    static final long APP_SWITCH_DELAY_TIME = 5*1000;
274
275    // How long we wait for a launched process to attach to the activity manager
276    // before we decide it's never going to come up for real.
277    static final int PROC_START_TIMEOUT = 10*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, when the process was
281    // started with a wrapper for instrumentation (such as Valgrind) because it
282    // could take much longer than usual.
283    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
284
285    // How long to wait after going idle before forcing apps to GC.
286    static final int GC_TIMEOUT = 5*1000;
287
288    // The minimum amount of time between successive GC requests for a process.
289    static final int GC_MIN_INTERVAL = 60*1000;
290
291    // The minimum amount of time between successive PSS requests for a process.
292    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process
295    // when the request is due to the memory state being lowered.
296    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
297
298    // The rate at which we check for apps using excessive power -- 15 mins.
299    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
300
301    // The minimum sample duration we will allow before deciding we have
302    // enough data on wake locks to start killing things.
303    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on CPU usage to start killing things.
307    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // How long we allow a receiver to run before giving up on it.
310    static final int BROADCAST_FG_TIMEOUT = 10*1000;
311    static final int BROADCAST_BG_TIMEOUT = 60*1000;
312
313    // How long we wait until we timeout on key dispatching.
314    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
315
316    // How long we wait until we timeout on key dispatching during instrumentation.
317    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
318
319    // Amount of time we wait for observers to handle a user switch before
320    // giving up on them and unfreezing the screen.
321    static final int USER_SWITCH_TIMEOUT = 2*1000;
322
323    // Maximum number of users we allow to be running at a time.
324    static final int MAX_RUNNING_USERS = 3;
325
326    // How long to wait in getAssistContextExtras for the activity and foreground services
327    // to respond with the result.
328    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
329
330    // Maximum number of persisted Uri grants a package is allowed
331    static final int MAX_PERSISTED_URI_GRANTS = 128;
332
333    static final int MY_PID = Process.myPid();
334
335    static final String[] EMPTY_STRING_ARRAY = new String[0];
336
337    // How many bytes to write into the dropbox log before truncating
338    static final int DROPBOX_MAX_SIZE = 256 * 1024;
339
340    /** All system services */
341    SystemServiceManager mSystemServiceManager;
342
343    /** Run all ActivityStacks through this */
344    ActivityStackSupervisor mStackSupervisor;
345
346    public IntentFirewall mIntentFirewall;
347
348    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
349    // default actuion automatically.  Important for devices without direct input
350    // devices.
351    private boolean mShowDialogs = true;
352
353    /**
354     * Description of a request to start a new activity, which has been held
355     * due to app switches being disabled.
356     */
357    static class PendingActivityLaunch {
358        final ActivityRecord r;
359        final ActivityRecord sourceRecord;
360        final int startFlags;
361        final ActivityStack stack;
362
363        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
364                int _startFlags, ActivityStack _stack) {
365            r = _r;
366            sourceRecord = _sourceRecord;
367            startFlags = _startFlags;
368            stack = _stack;
369        }
370    }
371
372    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
373            = new ArrayList<PendingActivityLaunch>();
374
375    BroadcastQueue mFgBroadcastQueue;
376    BroadcastQueue mBgBroadcastQueue;
377    // Convenient for easy iteration over the queues. Foreground is first
378    // so that dispatch of foreground broadcasts gets precedence.
379    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
380
381    BroadcastQueue broadcastQueueForIntent(Intent intent) {
382        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
383        if (DEBUG_BACKGROUND_BROADCAST) {
384            Slog.i(TAG, "Broadcast intent " + intent + " on "
385                    + (isFg ? "foreground" : "background")
386                    + " queue");
387        }
388        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
389    }
390
391    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
392        for (BroadcastQueue queue : mBroadcastQueues) {
393            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
394            if (r != null) {
395                return r;
396            }
397        }
398        return null;
399    }
400
401    /**
402     * Activity we have told the window manager to have key focus.
403     */
404    ActivityRecord mFocusedActivity = null;
405
406    /**
407     * List of intents that were used to start the most recent tasks.
408     */
409    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
410
411    public class PendingAssistExtras extends Binder implements Runnable {
412        public final ActivityRecord activity;
413        public boolean haveResult = false;
414        public Bundle result = null;
415        public PendingAssistExtras(ActivityRecord _activity) {
416            activity = _activity;
417        }
418        @Override
419        public void run() {
420            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
421            synchronized (this) {
422                haveResult = true;
423                notifyAll();
424            }
425        }
426    }
427
428    final ArrayList<PendingAssistExtras> mPendingAssistExtras
429            = new ArrayList<PendingAssistExtras>();
430
431    /**
432     * Process management.
433     */
434    final ProcessList mProcessList = new ProcessList();
435
436    /**
437     * All of the applications we currently have running organized by name.
438     * The keys are strings of the application package name (as
439     * returned by the package manager), and the keys are ApplicationRecord
440     * objects.
441     */
442    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
443
444    /**
445     * Tracking long-term execution of processes to look for abuse and other
446     * bad app behavior.
447     */
448    final ProcessStatsService mProcessStats;
449
450    /**
451     * The currently running isolated processes.
452     */
453    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
454
455    /**
456     * Counter for assigning isolated process uids, to avoid frequently reusing the
457     * same ones.
458     */
459    int mNextIsolatedProcessUid = 0;
460
461    /**
462     * The currently running heavy-weight process, if any.
463     */
464    ProcessRecord mHeavyWeightProcess = null;
465
466    /**
467     * The last time that various processes have crashed.
468     */
469    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
470
471    /**
472     * Information about a process that is currently marked as bad.
473     */
474    static final class BadProcessInfo {
475        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
476            this.time = time;
477            this.shortMsg = shortMsg;
478            this.longMsg = longMsg;
479            this.stack = stack;
480        }
481
482        final long time;
483        final String shortMsg;
484        final String longMsg;
485        final String stack;
486    }
487
488    /**
489     * Set of applications that we consider to be bad, and will reject
490     * incoming broadcasts from (which the user has no control over).
491     * Processes are added to this set when they have crashed twice within
492     * a minimum amount of time; they are removed from it when they are
493     * later restarted (hopefully due to some user action).  The value is the
494     * time it was added to the list.
495     */
496    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
497
498    /**
499     * All of the processes we currently have running organized by pid.
500     * The keys are the pid running the application.
501     *
502     * <p>NOTE: This object is protected by its own lock, NOT the global
503     * activity manager lock!
504     */
505    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
506
507    /**
508     * All of the processes that have been forced to be foreground.  The key
509     * is the pid of the caller who requested it (we hold a death
510     * link on it).
511     */
512    abstract class ForegroundToken implements IBinder.DeathRecipient {
513        int pid;
514        IBinder token;
515    }
516    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
517
518    /**
519     * List of records for processes that someone had tried to start before the
520     * system was ready.  We don't start them at that point, but ensure they
521     * are started by the time booting is complete.
522     */
523    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
524
525    /**
526     * List of persistent applications that are in the process
527     * of being started.
528     */
529    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Processes that are being forcibly torn down.
533     */
534    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
535
536    /**
537     * List of running applications, sorted by recent usage.
538     * The first entry in the list is the least recently used.
539     */
540    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
541
542    /**
543     * Where in mLruProcesses that the processes hosting activities start.
544     */
545    int mLruProcessActivityStart = 0;
546
547    /**
548     * Where in mLruProcesses that the processes hosting services start.
549     * This is after (lower index) than mLruProcessesActivityStart.
550     */
551    int mLruProcessServiceStart = 0;
552
553    /**
554     * List of processes that should gc as soon as things are idle.
555     */
556    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
557
558    /**
559     * Processes we want to collect PSS data from.
560     */
561    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Last time we requested PSS data of all processes.
565     */
566    long mLastFullPssTime = SystemClock.uptimeMillis();
567
568    /**
569     * This is the process holding what we currently consider to be
570     * the "home" activity.
571     */
572    ProcessRecord mHomeProcess;
573
574    /**
575     * This is the process holding the activity the user last visited that
576     * is in a different process from the one they are currently in.
577     */
578    ProcessRecord mPreviousProcess;
579
580    /**
581     * The time at which the previous process was last visible.
582     */
583    long mPreviousProcessVisibleTime;
584
585    /**
586     * Which uses have been started, so are allowed to run code.
587     */
588    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
589
590    /**
591     * LRU list of history of current users.  Most recently current is at the end.
592     */
593    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
594
595    /**
596     * Constant array of the users that are currently started.
597     */
598    int[] mStartedUserArray = new int[] { 0 };
599
600    /**
601     * Registered observers of the user switching mechanics.
602     */
603    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
604            = new RemoteCallbackList<IUserSwitchObserver>();
605
606    /**
607     * Currently active user switch.
608     */
609    Object mCurUserSwitchCallback;
610
611    /**
612     * Packages that the user has asked to have run in screen size
613     * compatibility mode instead of filling the screen.
614     */
615    final CompatModePackages mCompatModePackages;
616
617    /**
618     * Set of IntentSenderRecord objects that are currently active.
619     */
620    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
621            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
622
623    /**
624     * Fingerprints (hashCode()) of stack traces that we've
625     * already logged DropBox entries for.  Guarded by itself.  If
626     * something (rogue user app) forces this over
627     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
628     */
629    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
630    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
631
632    /**
633     * Strict Mode background batched logging state.
634     *
635     * The string buffer is guarded by itself, and its lock is also
636     * used to determine if another batched write is already
637     * in-flight.
638     */
639    private final StringBuilder mStrictModeBuffer = new StringBuilder();
640
641    /**
642     * Keeps track of all IIntentReceivers that have been registered for
643     * broadcasts.  Hash keys are the receiver IBinder, hash value is
644     * a ReceiverList.
645     */
646    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
647            new HashMap<IBinder, ReceiverList>();
648
649    /**
650     * Resolver for broadcast intents to registered receivers.
651     * Holds BroadcastFilter (subclass of IntentFilter).
652     */
653    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
654            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
655        @Override
656        protected boolean allowFilterResult(
657                BroadcastFilter filter, List<BroadcastFilter> dest) {
658            IBinder target = filter.receiverList.receiver.asBinder();
659            for (int i=dest.size()-1; i>=0; i--) {
660                if (dest.get(i).receiverList.receiver.asBinder() == target) {
661                    return false;
662                }
663            }
664            return true;
665        }
666
667        @Override
668        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
669            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
670                    || userId == filter.owningUserId) {
671                return super.newResult(filter, match, userId);
672            }
673            return null;
674        }
675
676        @Override
677        protected BroadcastFilter[] newArray(int size) {
678            return new BroadcastFilter[size];
679        }
680
681        @Override
682        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
683            return packageName.equals(filter.packageName);
684        }
685    };
686
687    /**
688     * State of all active sticky broadcasts per user.  Keys are the action of the
689     * sticky Intent, values are an ArrayList of all broadcasted intents with
690     * that action (which should usually be one).  The SparseArray is keyed
691     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
692     * for stickies that are sent to all users.
693     */
694    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
695            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
696
697    final ActiveServices mServices;
698
699    /**
700     * Backup/restore process management
701     */
702    String mBackupAppName = null;
703    BackupRecord mBackupTarget = null;
704
705    final ProviderMap mProviderMap;
706
707    /**
708     * List of content providers who have clients waiting for them.  The
709     * application is currently being launched and the provider will be
710     * removed from this list once it is published.
711     */
712    final ArrayList<ContentProviderRecord> mLaunchingProviders
713            = new ArrayList<ContentProviderRecord>();
714
715    /**
716     * File storing persisted {@link #mGrantedUriPermissions}.
717     */
718    private final AtomicFile mGrantFile;
719
720    /** XML constants used in {@link #mGrantFile} */
721    private static final String TAG_URI_GRANTS = "uri-grants";
722    private static final String TAG_URI_GRANT = "uri-grant";
723    private static final String ATTR_USER_HANDLE = "userHandle";
724    private static final String ATTR_SOURCE_PKG = "sourcePkg";
725    private static final String ATTR_TARGET_PKG = "targetPkg";
726    private static final String ATTR_URI = "uri";
727    private static final String ATTR_MODE_FLAGS = "modeFlags";
728    private static final String ATTR_CREATED_TIME = "createdTime";
729    private static final String ATTR_PREFIX = "prefix";
730
731    /**
732     * Global set of specific {@link Uri} permissions that have been granted.
733     * This optimized lookup structure maps from {@link UriPermission#targetUid}
734     * to {@link UriPermission#uri} to {@link UriPermission}.
735     */
736    @GuardedBy("this")
737    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
738            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
739
740    public static class GrantUri {
741        public final Uri uri;
742        public final boolean prefix;
743
744        public GrantUri(Uri uri, boolean prefix) {
745            this.uri = uri;
746            this.prefix = prefix;
747        }
748
749        @Override
750        public int hashCode() {
751            return toString().hashCode();
752        }
753
754        @Override
755        public boolean equals(Object o) {
756            if (o instanceof GrantUri) {
757                GrantUri other = (GrantUri) o;
758                return uri.equals(other.uri) && prefix == other.prefix;
759            }
760            return false;
761        }
762
763        @Override
764        public String toString() {
765            if (prefix) {
766                return uri.toString() + " [prefix]";
767            } else {
768                return uri.toString();
769            }
770        }
771    }
772
773    CoreSettingsObserver mCoreSettingsObserver;
774
775    /**
776     * Thread-local storage used to carry caller permissions over through
777     * indirect content-provider access.
778     */
779    private class Identity {
780        public int pid;
781        public int uid;
782
783        Identity(int _pid, int _uid) {
784            pid = _pid;
785            uid = _uid;
786        }
787    }
788
789    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
790
791    /**
792     * All information we have collected about the runtime performance of
793     * any user id that can impact battery performance.
794     */
795    final BatteryStatsService mBatteryStatsService;
796
797    /**
798     * Information about component usage
799     */
800    final UsageStatsService mUsageStatsService;
801
802    /**
803     * Information about and control over application operations
804     */
805    final AppOpsService mAppOpsService;
806
807    /**
808     * Current configuration information.  HistoryRecord objects are given
809     * a reference to this object to indicate which configuration they are
810     * currently running in, so this object must be kept immutable.
811     */
812    Configuration mConfiguration = new Configuration();
813
814    /**
815     * Current sequencing integer of the configuration, for skipping old
816     * configurations.
817     */
818    int mConfigurationSeq = 0;
819
820    /**
821     * Hardware-reported OpenGLES version.
822     */
823    final int GL_ES_VERSION;
824
825    /**
826     * List of initialization arguments to pass to all processes when binding applications to them.
827     * For example, references to the commonly used services.
828     */
829    HashMap<String, IBinder> mAppBindArgs;
830
831    /**
832     * Temporary to avoid allocations.  Protected by main lock.
833     */
834    final StringBuilder mStringBuilder = new StringBuilder(256);
835
836    /**
837     * Used to control how we initialize the service.
838     */
839    ComponentName mTopComponent;
840    String mTopAction = Intent.ACTION_MAIN;
841    String mTopData;
842    boolean mProcessesReady = false;
843    boolean mSystemReady = false;
844    boolean mBooting = false;
845    boolean mWaitingUpdate = false;
846    boolean mDidUpdate = false;
847    boolean mOnBattery = false;
848    boolean mLaunchWarningShown = false;
849
850    Context mContext;
851
852    int mFactoryTest;
853
854    boolean mCheckedForSetup;
855
856    /**
857     * The time at which we will allow normal application switches again,
858     * after a call to {@link #stopAppSwitches()}.
859     */
860    long mAppSwitchesAllowedTime;
861
862    /**
863     * This is set to true after the first switch after mAppSwitchesAllowedTime
864     * is set; any switches after that will clear the time.
865     */
866    boolean mDidAppSwitch;
867
868    /**
869     * Last time (in realtime) at which we checked for power usage.
870     */
871    long mLastPowerCheckRealtime;
872
873    /**
874     * Last time (in uptime) at which we checked for power usage.
875     */
876    long mLastPowerCheckUptime;
877
878    /**
879     * Set while we are wanting to sleep, to prevent any
880     * activities from being started/resumed.
881     */
882    private boolean mSleeping = false;
883
884    /**
885     * Set while we are running a voice interaction.  This overrides
886     * sleeping while it is active.
887     */
888    private boolean mRunningVoice = false;
889
890    /**
891     * State of external calls telling us if the device is asleep.
892     */
893    private boolean mWentToSleep = false;
894
895    /**
896     * State of external call telling us if the lock screen is shown.
897     */
898    private boolean mLockScreenShown = false;
899
900    /**
901     * Set if we are shutting down the system, similar to sleeping.
902     */
903    boolean mShuttingDown = false;
904
905    /**
906     * Current sequence id for oom_adj computation traversal.
907     */
908    int mAdjSeq = 0;
909
910    /**
911     * Current sequence id for process LRU updating.
912     */
913    int mLruSeq = 0;
914
915    /**
916     * Keep track of the non-cached/empty process we last found, to help
917     * determine how to distribute cached/empty processes next time.
918     */
919    int mNumNonCachedProcs = 0;
920
921    /**
922     * Keep track of the number of cached hidden procs, to balance oom adj
923     * distribution between those and empty procs.
924     */
925    int mNumCachedHiddenProcs = 0;
926
927    /**
928     * Keep track of the number of service processes we last found, to
929     * determine on the next iteration which should be B services.
930     */
931    int mNumServiceProcs = 0;
932    int mNewNumAServiceProcs = 0;
933    int mNewNumServiceProcs = 0;
934
935    /**
936     * Allow the current computed overall memory level of the system to go down?
937     * This is set to false when we are killing processes for reasons other than
938     * memory management, so that the now smaller process list will not be taken as
939     * an indication that memory is tighter.
940     */
941    boolean mAllowLowerMemLevel = false;
942
943    /**
944     * The last computed memory level, for holding when we are in a state that
945     * processes are going away for other reasons.
946     */
947    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
948
949    /**
950     * The last total number of process we have, to determine if changes actually look
951     * like a shrinking number of process due to lower RAM.
952     */
953    int mLastNumProcesses;
954
955    /**
956     * The uptime of the last time we performed idle maintenance.
957     */
958    long mLastIdleTime = SystemClock.uptimeMillis();
959
960    /**
961     * Total time spent with RAM that has been added in the past since the last idle time.
962     */
963    long mLowRamTimeSinceLastIdle = 0;
964
965    /**
966     * If RAM is currently low, when that horrible situation started.
967     */
968    long mLowRamStartTime = 0;
969
970    /**
971     * For reporting to battery stats the current top application.
972     */
973    private String mCurResumedPackage = null;
974    private int mCurResumedUid = -1;
975
976    /**
977     * For reporting to battery stats the apps currently running foreground
978     * service.  The ProcessMap is package/uid tuples; each of these contain
979     * an array of the currently foreground processes.
980     */
981    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
982            = new ProcessMap<ArrayList<ProcessRecord>>();
983
984    /**
985     * This is set if we had to do a delayed dexopt of an app before launching
986     * it, to increasing the ANR timeouts in that case.
987     */
988    boolean mDidDexOpt;
989
990    /**
991     * Set if the systemServer made a call to enterSafeMode.
992     */
993    boolean mSafeMode;
994
995    String mDebugApp = null;
996    boolean mWaitForDebugger = false;
997    boolean mDebugTransient = false;
998    String mOrigDebugApp = null;
999    boolean mOrigWaitForDebugger = false;
1000    boolean mAlwaysFinishActivities = false;
1001    IActivityController mController = null;
1002    String mProfileApp = null;
1003    ProcessRecord mProfileProc = null;
1004    String mProfileFile;
1005    ParcelFileDescriptor mProfileFd;
1006    int mProfileType = 0;
1007    boolean mAutoStopProfiler = false;
1008    String mOpenGlTraceApp = null;
1009
1010    static class ProcessChangeItem {
1011        static final int CHANGE_ACTIVITIES = 1<<0;
1012        static final int CHANGE_PROCESS_STATE = 1<<1;
1013        int changes;
1014        int uid;
1015        int pid;
1016        int processState;
1017        boolean foregroundActivities;
1018    }
1019
1020    final RemoteCallbackList<IProcessObserver> mProcessObservers
1021            = new RemoteCallbackList<IProcessObserver>();
1022    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1023
1024    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1025            = new ArrayList<ProcessChangeItem>();
1026    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1027            = new ArrayList<ProcessChangeItem>();
1028
1029    /**
1030     * Runtime CPU use collection thread.  This object's lock is used to
1031     * protect all related state.
1032     */
1033    final Thread mProcessCpuThread;
1034
1035    /**
1036     * Used to collect process stats when showing not responding dialog.
1037     * Protected by mProcessCpuThread.
1038     */
1039    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1040            MONITOR_THREAD_CPU_USAGE);
1041    final AtomicLong mLastCpuTime = new AtomicLong(0);
1042    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1043
1044    long mLastWriteTime = 0;
1045
1046    /**
1047     * Used to retain an update lock when the foreground activity is in
1048     * immersive mode.
1049     */
1050    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1051
1052    /**
1053     * Set to true after the system has finished booting.
1054     */
1055    boolean mBooted = false;
1056
1057    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1058    int mProcessLimitOverride = -1;
1059
1060    WindowManagerService mWindowManager;
1061
1062    final ActivityThread mSystemThread;
1063
1064    int mCurrentUserId = 0;
1065    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1066    private UserManagerService mUserManager;
1067
1068    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1069        final ProcessRecord mApp;
1070        final int mPid;
1071        final IApplicationThread mAppThread;
1072
1073        AppDeathRecipient(ProcessRecord app, int pid,
1074                IApplicationThread thread) {
1075            if (localLOGV) Slog.v(
1076                TAG, "New death recipient " + this
1077                + " for thread " + thread.asBinder());
1078            mApp = app;
1079            mPid = pid;
1080            mAppThread = thread;
1081        }
1082
1083        @Override
1084        public void binderDied() {
1085            if (localLOGV) Slog.v(
1086                TAG, "Death received in " + this
1087                + " for thread " + mAppThread.asBinder());
1088            synchronized(ActivityManagerService.this) {
1089                appDiedLocked(mApp, mPid, mAppThread);
1090            }
1091        }
1092    }
1093
1094    static final int SHOW_ERROR_MSG = 1;
1095    static final int SHOW_NOT_RESPONDING_MSG = 2;
1096    static final int SHOW_FACTORY_ERROR_MSG = 3;
1097    static final int UPDATE_CONFIGURATION_MSG = 4;
1098    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1099    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1100    static final int SERVICE_TIMEOUT_MSG = 12;
1101    static final int UPDATE_TIME_ZONE = 13;
1102    static final int SHOW_UID_ERROR_MSG = 14;
1103    static final int IM_FEELING_LUCKY_MSG = 15;
1104    static final int PROC_START_TIMEOUT_MSG = 20;
1105    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1106    static final int KILL_APPLICATION_MSG = 22;
1107    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1108    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1109    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1110    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1111    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1112    static final int CLEAR_DNS_CACHE_MSG = 28;
1113    static final int UPDATE_HTTP_PROXY_MSG = 29;
1114    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1115    static final int DISPATCH_PROCESSES_CHANGED = 31;
1116    static final int DISPATCH_PROCESS_DIED = 32;
1117    static final int REPORT_MEM_USAGE_MSG = 33;
1118    static final int REPORT_USER_SWITCH_MSG = 34;
1119    static final int CONTINUE_USER_SWITCH_MSG = 35;
1120    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1121    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1122    static final int PERSIST_URI_GRANTS_MSG = 38;
1123    static final int REQUEST_ALL_PSS_MSG = 39;
1124    static final int START_PROFILES_MSG = 40;
1125    static final int UPDATE_TIME = 41;
1126    static final int SYSTEM_USER_START_MSG = 42;
1127    static final int SYSTEM_USER_CURRENT_MSG = 43;
1128
1129    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1130    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1131    static final int FIRST_COMPAT_MODE_MSG = 300;
1132    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1133
1134    AlertDialog mUidAlert;
1135    CompatModeDialog mCompatModeDialog;
1136    long mLastMemUsageReportTime = 0;
1137
1138    /**
1139     * Flag whether the current user is a "monkey", i.e. whether
1140     * the UI is driven by a UI automation tool.
1141     */
1142    private boolean mUserIsMonkey;
1143
1144    final ServiceThread mHandlerThread;
1145    final MainHandler mHandler;
1146
1147    final class MainHandler extends Handler {
1148        public MainHandler(Looper looper) {
1149            super(looper, null, true);
1150        }
1151
1152        @Override
1153        public void handleMessage(Message msg) {
1154            switch (msg.what) {
1155            case SHOW_ERROR_MSG: {
1156                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1157                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1158                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1159                synchronized (ActivityManagerService.this) {
1160                    ProcessRecord proc = (ProcessRecord)data.get("app");
1161                    AppErrorResult res = (AppErrorResult) data.get("result");
1162                    if (proc != null && proc.crashDialog != null) {
1163                        Slog.e(TAG, "App already has crash dialog: " + proc);
1164                        if (res != null) {
1165                            res.set(0);
1166                        }
1167                        return;
1168                    }
1169                    if (!showBackground && UserHandle.getAppId(proc.uid)
1170                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1171                            && proc.pid != MY_PID) {
1172                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1173                        if (res != null) {
1174                            res.set(0);
1175                        }
1176                        return;
1177                    }
1178                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1179                        Dialog d = new AppErrorDialog(mContext,
1180                                ActivityManagerService.this, res, proc);
1181                        d.show();
1182                        proc.crashDialog = d;
1183                    } else {
1184                        // The device is asleep, so just pretend that the user
1185                        // saw a crash dialog and hit "force quit".
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                    }
1190                }
1191
1192                ensureBootCompleted();
1193            } break;
1194            case SHOW_NOT_RESPONDING_MSG: {
1195                synchronized (ActivityManagerService.this) {
1196                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                    ProcessRecord proc = (ProcessRecord)data.get("app");
1198                    if (proc != null && proc.anrDialog != null) {
1199                        Slog.e(TAG, "App already has anr dialog: " + proc);
1200                        return;
1201                    }
1202
1203                    Intent intent = new Intent("android.intent.action.ANR");
1204                    if (!mProcessesReady) {
1205                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1206                                | Intent.FLAG_RECEIVER_FOREGROUND);
1207                    }
1208                    broadcastIntentLocked(null, null, intent,
1209                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1210                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1211
1212                    if (mShowDialogs) {
1213                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1214                                mContext, proc, (ActivityRecord)data.get("activity"),
1215                                msg.arg1 != 0);
1216                        d.show();
1217                        proc.anrDialog = d;
1218                    } else {
1219                        // Just kill the app if there is no dialog to be shown.
1220                        killAppAtUsersRequest(proc, null);
1221                    }
1222                }
1223
1224                ensureBootCompleted();
1225            } break;
1226            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1227                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1228                synchronized (ActivityManagerService.this) {
1229                    ProcessRecord proc = (ProcessRecord) data.get("app");
1230                    if (proc == null) {
1231                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1232                        break;
1233                    }
1234                    if (proc.crashDialog != null) {
1235                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1236                        return;
1237                    }
1238                    AppErrorResult res = (AppErrorResult) data.get("result");
1239                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1240                        Dialog d = new StrictModeViolationDialog(mContext,
1241                                ActivityManagerService.this, res, proc);
1242                        d.show();
1243                        proc.crashDialog = d;
1244                    } else {
1245                        // The device is asleep, so just pretend that the user
1246                        // saw a crash dialog and hit "force quit".
1247                        res.set(0);
1248                    }
1249                }
1250                ensureBootCompleted();
1251            } break;
1252            case SHOW_FACTORY_ERROR_MSG: {
1253                Dialog d = new FactoryErrorDialog(
1254                    mContext, msg.getData().getCharSequence("msg"));
1255                d.show();
1256                ensureBootCompleted();
1257            } break;
1258            case UPDATE_CONFIGURATION_MSG: {
1259                final ContentResolver resolver = mContext.getContentResolver();
1260                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1261            } break;
1262            case GC_BACKGROUND_PROCESSES_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    performAppGcsIfAppropriateLocked();
1265                }
1266            } break;
1267            case WAIT_FOR_DEBUGGER_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord app = (ProcessRecord)msg.obj;
1270                    if (msg.arg1 != 0) {
1271                        if (!app.waitedForDebugger) {
1272                            Dialog d = new AppWaitingForDebuggerDialog(
1273                                    ActivityManagerService.this,
1274                                    mContext, app);
1275                            app.waitDialog = d;
1276                            app.waitedForDebugger = true;
1277                            d.show();
1278                        }
1279                    } else {
1280                        if (app.waitDialog != null) {
1281                            app.waitDialog.dismiss();
1282                            app.waitDialog = null;
1283                        }
1284                    }
1285                }
1286            } break;
1287            case SERVICE_TIMEOUT_MSG: {
1288                if (mDidDexOpt) {
1289                    mDidDexOpt = false;
1290                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1291                    nmsg.obj = msg.obj;
1292                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1293                    return;
1294                }
1295                mServices.serviceTimeout((ProcessRecord)msg.obj);
1296            } break;
1297            case UPDATE_TIME_ZONE: {
1298                synchronized (ActivityManagerService.this) {
1299                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1300                        ProcessRecord r = mLruProcesses.get(i);
1301                        if (r.thread != null) {
1302                            try {
1303                                r.thread.updateTimeZone();
1304                            } catch (RemoteException ex) {
1305                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1306                            }
1307                        }
1308                    }
1309                }
1310            } break;
1311            case CLEAR_DNS_CACHE_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1314                        ProcessRecord r = mLruProcesses.get(i);
1315                        if (r.thread != null) {
1316                            try {
1317                                r.thread.clearDnsCache();
1318                            } catch (RemoteException ex) {
1319                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1320                            }
1321                        }
1322                    }
1323                }
1324            } break;
1325            case UPDATE_HTTP_PROXY_MSG: {
1326                ProxyProperties proxy = (ProxyProperties)msg.obj;
1327                String host = "";
1328                String port = "";
1329                String exclList = "";
1330                String pacFileUrl = null;
1331                if (proxy != null) {
1332                    host = proxy.getHost();
1333                    port = Integer.toString(proxy.getPort());
1334                    exclList = proxy.getExclusionList();
1335                    pacFileUrl = proxy.getPacFileUrl();
1336                }
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update http proxy for: " +
1345                                        r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case SHOW_UID_ERROR_MSG: {
1352                String title = "System UIDs Inconsistent";
1353                String text = "UIDs on the system are inconsistent, you need to wipe your"
1354                        + " data partition or your device will be unstable.";
1355                Log.e(TAG, title + ": " + text);
1356                if (mShowDialogs) {
1357                    // XXX This is a temporary dialog, no need to localize.
1358                    AlertDialog d = new BaseErrorDialog(mContext);
1359                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1360                    d.setCancelable(false);
1361                    d.setTitle(title);
1362                    d.setMessage(text);
1363                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1364                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1365                    mUidAlert = d;
1366                    d.show();
1367                }
1368            } break;
1369            case IM_FEELING_LUCKY_MSG: {
1370                if (mUidAlert != null) {
1371                    mUidAlert.dismiss();
1372                    mUidAlert = null;
1373                }
1374            } break;
1375            case PROC_START_TIMEOUT_MSG: {
1376                if (mDidDexOpt) {
1377                    mDidDexOpt = false;
1378                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1379                    nmsg.obj = msg.obj;
1380                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1381                    return;
1382                }
1383                ProcessRecord app = (ProcessRecord)msg.obj;
1384                synchronized (ActivityManagerService.this) {
1385                    processStartTimedOutLocked(app);
1386                }
1387            } break;
1388            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1389                synchronized (ActivityManagerService.this) {
1390                    doPendingActivityLaunchesLocked(true);
1391                }
1392            } break;
1393            case KILL_APPLICATION_MSG: {
1394                synchronized (ActivityManagerService.this) {
1395                    int appid = msg.arg1;
1396                    boolean restart = (msg.arg2 == 1);
1397                    Bundle bundle = (Bundle)msg.obj;
1398                    String pkg = bundle.getString("pkg");
1399                    String reason = bundle.getString("reason");
1400                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1401                            false, UserHandle.USER_ALL, reason);
1402                }
1403            } break;
1404            case FINALIZE_PENDING_INTENT_MSG: {
1405                ((PendingIntentRecord)msg.obj).completeFinalize();
1406            } break;
1407            case POST_HEAVY_NOTIFICATION_MSG: {
1408                INotificationManager inm = NotificationManager.getService();
1409                if (inm == null) {
1410                    return;
1411                }
1412
1413                ActivityRecord root = (ActivityRecord)msg.obj;
1414                ProcessRecord process = root.app;
1415                if (process == null) {
1416                    return;
1417                }
1418
1419                try {
1420                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1421                    String text = mContext.getString(R.string.heavy_weight_notification,
1422                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1423                    Notification notification = new Notification();
1424                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1425                    notification.when = 0;
1426                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1427                    notification.tickerText = text;
1428                    notification.defaults = 0; // please be quiet
1429                    notification.sound = null;
1430                    notification.vibrate = null;
1431                    notification.setLatestEventInfo(context, text,
1432                            mContext.getText(R.string.heavy_weight_notification_detail),
1433                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1434                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1435                                    new UserHandle(root.userId)));
1436
1437                    try {
1438                        int[] outId = new int[1];
1439                        inm.enqueueNotificationWithTag("android", "android", null,
1440                                R.string.heavy_weight_notification,
1441                                notification, outId, root.userId);
1442                    } catch (RuntimeException e) {
1443                        Slog.w(ActivityManagerService.TAG,
1444                                "Error showing notification for heavy-weight app", e);
1445                    } catch (RemoteException e) {
1446                    }
1447                } catch (NameNotFoundException e) {
1448                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1449                }
1450            } break;
1451            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456                try {
1457                    inm.cancelNotificationWithTag("android", null,
1458                            R.string.heavy_weight_notification,  msg.arg1);
1459                } catch (RuntimeException e) {
1460                    Slog.w(ActivityManagerService.TAG,
1461                            "Error canceling notification for service", e);
1462                } catch (RemoteException e) {
1463                }
1464            } break;
1465            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1466                synchronized (ActivityManagerService.this) {
1467                    checkExcessivePowerUsageLocked(true);
1468                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1469                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1470                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1471                }
1472            } break;
1473            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    ActivityRecord ar = (ActivityRecord)msg.obj;
1476                    if (mCompatModeDialog != null) {
1477                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1478                                ar.info.applicationInfo.packageName)) {
1479                            return;
1480                        }
1481                        mCompatModeDialog.dismiss();
1482                        mCompatModeDialog = null;
1483                    }
1484                    if (ar != null && false) {
1485                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1486                                ar.packageName)) {
1487                            int mode = mCompatModePackages.computeCompatModeLocked(
1488                                    ar.info.applicationInfo);
1489                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1490                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1491                                mCompatModeDialog = new CompatModeDialog(
1492                                        ActivityManagerService.this, mContext,
1493                                        ar.info.applicationInfo);
1494                                mCompatModeDialog.show();
1495                            }
1496                        }
1497                    }
1498                }
1499                break;
1500            }
1501            case DISPATCH_PROCESSES_CHANGED: {
1502                dispatchProcessesChanged();
1503                break;
1504            }
1505            case DISPATCH_PROCESS_DIED: {
1506                final int pid = msg.arg1;
1507                final int uid = msg.arg2;
1508                dispatchProcessDied(pid, uid);
1509                break;
1510            }
1511            case REPORT_MEM_USAGE_MSG: {
1512                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1513                Thread thread = new Thread() {
1514                    @Override public void run() {
1515                        final SparseArray<ProcessMemInfo> infoMap
1516                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1517                        for (int i=0, N=memInfos.size(); i<N; i++) {
1518                            ProcessMemInfo mi = memInfos.get(i);
1519                            infoMap.put(mi.pid, mi);
1520                        }
1521                        updateCpuStatsNow();
1522                        synchronized (mProcessCpuThread) {
1523                            final int N = mProcessCpuTracker.countStats();
1524                            for (int i=0; i<N; i++) {
1525                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1526                                if (st.vsize > 0) {
1527                                    long pss = Debug.getPss(st.pid, null);
1528                                    if (pss > 0) {
1529                                        if (infoMap.indexOfKey(st.pid) < 0) {
1530                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1531                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1532                                            mi.pss = pss;
1533                                            memInfos.add(mi);
1534                                        }
1535                                    }
1536                                }
1537                            }
1538                        }
1539
1540                        long totalPss = 0;
1541                        for (int i=0, N=memInfos.size(); i<N; i++) {
1542                            ProcessMemInfo mi = memInfos.get(i);
1543                            if (mi.pss == 0) {
1544                                mi.pss = Debug.getPss(mi.pid, null);
1545                            }
1546                            totalPss += mi.pss;
1547                        }
1548                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1549                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1550                                if (lhs.oomAdj != rhs.oomAdj) {
1551                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1552                                }
1553                                if (lhs.pss != rhs.pss) {
1554                                    return lhs.pss < rhs.pss ? 1 : -1;
1555                                }
1556                                return 0;
1557                            }
1558                        });
1559
1560                        StringBuilder tag = new StringBuilder(128);
1561                        StringBuilder stack = new StringBuilder(128);
1562                        tag.append("Low on memory -- ");
1563                        appendMemBucket(tag, totalPss, "total", false);
1564                        appendMemBucket(stack, totalPss, "total", true);
1565
1566                        StringBuilder logBuilder = new StringBuilder(1024);
1567                        logBuilder.append("Low on memory:\n");
1568
1569                        boolean firstLine = true;
1570                        int lastOomAdj = Integer.MIN_VALUE;
1571                        for (int i=0, N=memInfos.size(); i<N; i++) {
1572                            ProcessMemInfo mi = memInfos.get(i);
1573
1574                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1575                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1576                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1577                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1578                                if (lastOomAdj != mi.oomAdj) {
1579                                    lastOomAdj = mi.oomAdj;
1580                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1581                                        tag.append(" / ");
1582                                    }
1583                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1584                                        if (firstLine) {
1585                                            stack.append(":");
1586                                            firstLine = false;
1587                                        }
1588                                        stack.append("\n\t at ");
1589                                    } else {
1590                                        stack.append("$");
1591                                    }
1592                                } else {
1593                                    tag.append(" ");
1594                                    stack.append("$");
1595                                }
1596                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1597                                    appendMemBucket(tag, mi.pss, mi.name, false);
1598                                }
1599                                appendMemBucket(stack, mi.pss, mi.name, true);
1600                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1601                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1602                                    stack.append("(");
1603                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1604                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1605                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1606                                            stack.append(":");
1607                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1608                                        }
1609                                    }
1610                                    stack.append(")");
1611                                }
1612                            }
1613
1614                            logBuilder.append("  ");
1615                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1616                            logBuilder.append(' ');
1617                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1618                            logBuilder.append(' ');
1619                            ProcessList.appendRamKb(logBuilder, mi.pss);
1620                            logBuilder.append(" kB: ");
1621                            logBuilder.append(mi.name);
1622                            logBuilder.append(" (");
1623                            logBuilder.append(mi.pid);
1624                            logBuilder.append(") ");
1625                            logBuilder.append(mi.adjType);
1626                            logBuilder.append('\n');
1627                            if (mi.adjReason != null) {
1628                                logBuilder.append("                      ");
1629                                logBuilder.append(mi.adjReason);
1630                                logBuilder.append('\n');
1631                            }
1632                        }
1633
1634                        logBuilder.append("           ");
1635                        ProcessList.appendRamKb(logBuilder, totalPss);
1636                        logBuilder.append(" kB: TOTAL\n");
1637
1638                        long[] infos = new long[Debug.MEMINFO_COUNT];
1639                        Debug.getMemInfo(infos);
1640                        logBuilder.append("  MemInfo: ");
1641                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1642                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1643                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1644                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1646                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1647                            logBuilder.append("  ZRAM: ");
1648                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1649                            logBuilder.append(" kB RAM, ");
1650                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1651                            logBuilder.append(" kB swap total, ");
1652                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1653                            logBuilder.append(" kB swap free\n");
1654                        }
1655                        Slog.i(TAG, logBuilder.toString());
1656
1657                        StringBuilder dropBuilder = new StringBuilder(1024);
1658                        /*
1659                        StringWriter oomSw = new StringWriter();
1660                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1661                        StringWriter catSw = new StringWriter();
1662                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1663                        String[] emptyArgs = new String[] { };
1664                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1665                        oomPw.flush();
1666                        String oomString = oomSw.toString();
1667                        */
1668                        dropBuilder.append(stack);
1669                        dropBuilder.append('\n');
1670                        dropBuilder.append('\n');
1671                        dropBuilder.append(logBuilder);
1672                        dropBuilder.append('\n');
1673                        /*
1674                        dropBuilder.append(oomString);
1675                        dropBuilder.append('\n');
1676                        */
1677                        StringWriter catSw = new StringWriter();
1678                        synchronized (ActivityManagerService.this) {
1679                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1680                            String[] emptyArgs = new String[] { };
1681                            catPw.println();
1682                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1683                            catPw.println();
1684                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1685                                    false, false, null);
1686                            catPw.println();
1687                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1688                            catPw.flush();
1689                        }
1690                        dropBuilder.append(catSw.toString());
1691                        addErrorToDropBox("lowmem", null, "system_server", null,
1692                                null, tag.toString(), dropBuilder.toString(), null, null);
1693                        //Slog.i(TAG, "Sent to dropbox:");
1694                        //Slog.i(TAG, dropBuilder.toString());
1695                        synchronized (ActivityManagerService.this) {
1696                            long now = SystemClock.uptimeMillis();
1697                            if (mLastMemUsageReportTime < now) {
1698                                mLastMemUsageReportTime = now;
1699                            }
1700                        }
1701                    }
1702                };
1703                thread.start();
1704                break;
1705            }
1706            case REPORT_USER_SWITCH_MSG: {
1707                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1708                break;
1709            }
1710            case CONTINUE_USER_SWITCH_MSG: {
1711                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1712                break;
1713            }
1714            case USER_SWITCH_TIMEOUT_MSG: {
1715                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1716                break;
1717            }
1718            case IMMERSIVE_MODE_LOCK_MSG: {
1719                final boolean nextState = (msg.arg1 != 0);
1720                if (mUpdateLock.isHeld() != nextState) {
1721                    if (DEBUG_IMMERSIVE) {
1722                        final ActivityRecord r = (ActivityRecord) msg.obj;
1723                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1724                    }
1725                    if (nextState) {
1726                        mUpdateLock.acquire();
1727                    } else {
1728                        mUpdateLock.release();
1729                    }
1730                }
1731                break;
1732            }
1733            case PERSIST_URI_GRANTS_MSG: {
1734                writeGrantedUriPermissions();
1735                break;
1736            }
1737            case REQUEST_ALL_PSS_MSG: {
1738                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1739                break;
1740            }
1741            case START_PROFILES_MSG: {
1742                synchronized (ActivityManagerService.this) {
1743                    startProfilesLocked();
1744                }
1745                break;
1746            }
1747            case UPDATE_TIME: {
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760                break;
1761            }
1762            case SYSTEM_USER_START_MSG: {
1763                mSystemServiceManager.startUser(msg.arg1);
1764                break;
1765            }
1766            case SYSTEM_USER_CURRENT_MSG: {
1767                mSystemServiceManager.switchUser(msg.arg1);
1768                break;
1769            }
1770            }
1771        }
1772    };
1773
1774    static final int COLLECT_PSS_BG_MSG = 1;
1775
1776    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1777        @Override
1778        public void handleMessage(Message msg) {
1779            switch (msg.what) {
1780            case COLLECT_PSS_BG_MSG: {
1781                int i=0, num=0;
1782                long start = SystemClock.uptimeMillis();
1783                long[] tmp = new long[1];
1784                do {
1785                    ProcessRecord proc;
1786                    int procState;
1787                    int pid;
1788                    synchronized (ActivityManagerService.this) {
1789                        if (i >= mPendingPssProcesses.size()) {
1790                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1791                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1792                            mPendingPssProcesses.clear();
1793                            return;
1794                        }
1795                        proc = mPendingPssProcesses.get(i);
1796                        procState = proc.pssProcState;
1797                        if (proc.thread != null && procState == proc.setProcState) {
1798                            pid = proc.pid;
1799                        } else {
1800                            proc = null;
1801                            pid = 0;
1802                        }
1803                        i++;
1804                    }
1805                    if (proc != null) {
1806                        long pss = Debug.getPss(pid, tmp);
1807                        synchronized (ActivityManagerService.this) {
1808                            if (proc.thread != null && proc.setProcState == procState
1809                                    && proc.pid == pid) {
1810                                num++;
1811                                proc.lastPssTime = SystemClock.uptimeMillis();
1812                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1813                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1814                                        + ": " + pss + " lastPss=" + proc.lastPss
1815                                        + " state=" + ProcessList.makeProcStateString(procState));
1816                                if (proc.initialIdlePss == 0) {
1817                                    proc.initialIdlePss = pss;
1818                                }
1819                                proc.lastPss = pss;
1820                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1821                                    proc.lastCachedPss = pss;
1822                                }
1823                            }
1824                        }
1825                    }
1826                } while (true);
1827            }
1828            }
1829        }
1830    };
1831
1832    /**
1833     * Monitor for package changes and update our internal state.
1834     */
1835    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1836        @Override
1837        public void onPackageRemoved(String packageName, int uid) {
1838            // Remove all tasks with activities in the specified package from the list of recent tasks
1839            synchronized (ActivityManagerService.this) {
1840                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1841                    TaskRecord tr = mRecentTasks.get(i);
1842                    ComponentName cn = tr.intent.getComponent();
1843                    if (cn != null && cn.getPackageName().equals(packageName)) {
1844                        // If the package name matches, remove the task and kill the process
1845                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1846                    }
1847                }
1848            }
1849        }
1850
1851        @Override
1852        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1853            onPackageModified(packageName);
1854            return true;
1855        }
1856
1857        @Override
1858        public void onPackageModified(String packageName) {
1859            final PackageManager pm = mContext.getPackageManager();
1860            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1861                    new ArrayList<Pair<Intent, Integer>>();
1862            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1863            // Copy the list of recent tasks so that we don't hold onto the lock on
1864            // ActivityManagerService for long periods while checking if components exist.
1865            synchronized (ActivityManagerService.this) {
1866                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1867                    TaskRecord tr = mRecentTasks.get(i);
1868                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1869                }
1870            }
1871            // Check the recent tasks and filter out all tasks with components that no longer exist.
1872            Intent tmpI = new Intent();
1873            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1874                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1875                ComponentName cn = p.first.getComponent();
1876                if (cn != null && cn.getPackageName().equals(packageName)) {
1877                    try {
1878                        // Add the task to the list to remove if the component no longer exists
1879                        tmpI.setComponent(cn);
1880                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1881                            tasksToRemove.add(p.second);
1882                        }
1883                    } catch (Exception e) {}
1884                }
1885            }
1886            // Prune all the tasks with removed components from the list of recent tasks
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1889                    // Remove the task but don't kill the process (since other components in that
1890                    // package may still be running and in the background)
1891                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1892                }
1893            }
1894        }
1895
1896        @Override
1897        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1898            // Force stop the specified packages
1899            if (packages != null) {
1900                for (String pkg : packages) {
1901                    synchronized (ActivityManagerService.this) {
1902                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1903                                "finished booting")) {
1904                            return true;
1905                        }
1906                    }
1907                }
1908            }
1909            return false;
1910        }
1911    };
1912
1913    public void setSystemProcess() {
1914        try {
1915            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1916            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1917            ServiceManager.addService("meminfo", new MemBinder(this));
1918            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1919            ServiceManager.addService("dbinfo", new DbBinder(this));
1920            if (MONITOR_CPU_USAGE) {
1921                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1922            }
1923            ServiceManager.addService("permission", new PermissionController(this));
1924
1925            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1926                    "android", STOCK_PM_FLAGS);
1927            mSystemThread.installSystemApplicationInfo(info);
1928
1929            synchronized (this) {
1930                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1931                app.persistent = true;
1932                app.pid = MY_PID;
1933                app.maxAdj = ProcessList.SYSTEM_ADJ;
1934                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1935                mProcessNames.put(app.processName, app.uid, app);
1936                synchronized (mPidsSelfLocked) {
1937                    mPidsSelfLocked.put(app.pid, app);
1938                }
1939                updateLruProcessLocked(app, false, null);
1940                updateOomAdjLocked();
1941            }
1942        } catch (PackageManager.NameNotFoundException e) {
1943            throw new RuntimeException(
1944                    "Unable to find android system package", e);
1945        }
1946    }
1947
1948    public void setWindowManager(WindowManagerService wm) {
1949        mWindowManager = wm;
1950        mStackSupervisor.setWindowManager(wm);
1951    }
1952
1953    public void startObservingNativeCrashes() {
1954        final NativeCrashListener ncl = new NativeCrashListener(this);
1955        ncl.start();
1956    }
1957
1958    public IAppOpsService getAppOpsService() {
1959        return mAppOpsService;
1960    }
1961
1962    static class MemBinder extends Binder {
1963        ActivityManagerService mActivityManagerService;
1964        MemBinder(ActivityManagerService activityManagerService) {
1965            mActivityManagerService = activityManagerService;
1966        }
1967
1968        @Override
1969        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1970            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1971                    != PackageManager.PERMISSION_GRANTED) {
1972                pw.println("Permission Denial: can't dump meminfo from from pid="
1973                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1974                        + " without permission " + android.Manifest.permission.DUMP);
1975                return;
1976            }
1977
1978            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1979        }
1980    }
1981
1982    static class GraphicsBinder extends Binder {
1983        ActivityManagerService mActivityManagerService;
1984        GraphicsBinder(ActivityManagerService activityManagerService) {
1985            mActivityManagerService = activityManagerService;
1986        }
1987
1988        @Override
1989        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1990            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1991                    != PackageManager.PERMISSION_GRANTED) {
1992                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1993                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1994                        + " without permission " + android.Manifest.permission.DUMP);
1995                return;
1996            }
1997
1998            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1999        }
2000    }
2001
2002    static class DbBinder extends Binder {
2003        ActivityManagerService mActivityManagerService;
2004        DbBinder(ActivityManagerService activityManagerService) {
2005            mActivityManagerService = activityManagerService;
2006        }
2007
2008        @Override
2009        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2010            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2011                    != PackageManager.PERMISSION_GRANTED) {
2012                pw.println("Permission Denial: can't dump dbinfo from from pid="
2013                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2014                        + " without permission " + android.Manifest.permission.DUMP);
2015                return;
2016            }
2017
2018            mActivityManagerService.dumpDbInfo(fd, pw, args);
2019        }
2020    }
2021
2022    static class CpuBinder extends Binder {
2023        ActivityManagerService mActivityManagerService;
2024        CpuBinder(ActivityManagerService activityManagerService) {
2025            mActivityManagerService = activityManagerService;
2026        }
2027
2028        @Override
2029        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2030            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2031                    != PackageManager.PERMISSION_GRANTED) {
2032                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2033                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2034                        + " without permission " + android.Manifest.permission.DUMP);
2035                return;
2036            }
2037
2038            synchronized (mActivityManagerService.mProcessCpuThread) {
2039                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2040                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2041                        SystemClock.uptimeMillis()));
2042            }
2043        }
2044    }
2045
2046    public static final class Lifecycle extends SystemService {
2047        private final ActivityManagerService mService;
2048
2049        public Lifecycle(Context context) {
2050            super(context);
2051            mService = new ActivityManagerService(context);
2052        }
2053
2054        @Override
2055        public void onStart() {
2056            mService.start();
2057        }
2058
2059        public ActivityManagerService getService() {
2060            return mService;
2061        }
2062    }
2063
2064    // Note: This method is invoked on the main thread but may need to attach various
2065    // handlers to other threads.  So take care to be explicit about the looper.
2066    public ActivityManagerService(Context systemContext) {
2067        mContext = systemContext;
2068        mFactoryTest = FactoryTest.getMode();
2069        mSystemThread = ActivityThread.currentActivityThread();
2070
2071        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2072
2073        mHandlerThread = new ServiceThread(TAG,
2074                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2075        mHandlerThread.start();
2076        mHandler = new MainHandler(mHandlerThread.getLooper());
2077
2078        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2079                "foreground", BROADCAST_FG_TIMEOUT, false);
2080        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2081                "background", BROADCAST_BG_TIMEOUT, true);
2082        mBroadcastQueues[0] = mFgBroadcastQueue;
2083        mBroadcastQueues[1] = mBgBroadcastQueue;
2084
2085        mServices = new ActiveServices(this);
2086        mProviderMap = new ProviderMap(this);
2087
2088        // TODO: Move creation of battery stats service outside of activity manager service.
2089        File dataDir = Environment.getDataDirectory();
2090        File systemDir = new File(dataDir, "system");
2091        systemDir.mkdirs();
2092        mBatteryStatsService = new BatteryStatsService(new File(
2093                systemDir, "batterystats.bin").toString(), mHandler);
2094        mBatteryStatsService.getActiveStatistics().readLocked();
2095        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2096        mOnBattery = DEBUG_POWER ? true
2097                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2098        mBatteryStatsService.getActiveStatistics().setCallback(this);
2099
2100        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2101
2102        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2103        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2104
2105        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2106
2107        // User 0 is the first and only user that runs at boot.
2108        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2109        mUserLru.add(Integer.valueOf(0));
2110        updateStartedUserArrayLocked();
2111
2112        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2113            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2114
2115        mConfiguration.setToDefaults();
2116        mConfiguration.setLocale(Locale.getDefault());
2117
2118        mConfigurationSeq = mConfiguration.seq = 1;
2119        mProcessCpuTracker.init();
2120
2121        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2122        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2123        mStackSupervisor = new ActivityStackSupervisor(this);
2124
2125        mProcessCpuThread = new Thread("CpuTracker") {
2126            @Override
2127            public void run() {
2128                while (true) {
2129                    try {
2130                        try {
2131                            synchronized(this) {
2132                                final long now = SystemClock.uptimeMillis();
2133                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2134                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2135                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2136                                //        + ", write delay=" + nextWriteDelay);
2137                                if (nextWriteDelay < nextCpuDelay) {
2138                                    nextCpuDelay = nextWriteDelay;
2139                                }
2140                                if (nextCpuDelay > 0) {
2141                                    mProcessCpuMutexFree.set(true);
2142                                    this.wait(nextCpuDelay);
2143                                }
2144                            }
2145                        } catch (InterruptedException e) {
2146                        }
2147                        updateCpuStatsNow();
2148                    } catch (Exception e) {
2149                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2150                    }
2151                }
2152            }
2153        };
2154
2155        Watchdog.getInstance().addMonitor(this);
2156        Watchdog.getInstance().addThread(mHandler);
2157    }
2158
2159    public void setSystemServiceManager(SystemServiceManager mgr) {
2160        mSystemServiceManager = mgr;
2161    }
2162
2163    private void start() {
2164        mProcessCpuThread.start();
2165
2166        mBatteryStatsService.publish(mContext);
2167        mUsageStatsService.publish(mContext);
2168        mAppOpsService.publish(mContext);
2169
2170        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2171    }
2172
2173    @Override
2174    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2175            throws RemoteException {
2176        if (code == SYSPROPS_TRANSACTION) {
2177            // We need to tell all apps about the system property change.
2178            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2179            synchronized(this) {
2180                final int NP = mProcessNames.getMap().size();
2181                for (int ip=0; ip<NP; ip++) {
2182                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2183                    final int NA = apps.size();
2184                    for (int ia=0; ia<NA; ia++) {
2185                        ProcessRecord app = apps.valueAt(ia);
2186                        if (app.thread != null) {
2187                            procs.add(app.thread.asBinder());
2188                        }
2189                    }
2190                }
2191            }
2192
2193            int N = procs.size();
2194            for (int i=0; i<N; i++) {
2195                Parcel data2 = Parcel.obtain();
2196                try {
2197                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2198                } catch (RemoteException e) {
2199                }
2200                data2.recycle();
2201            }
2202        }
2203        try {
2204            return super.onTransact(code, data, reply, flags);
2205        } catch (RuntimeException e) {
2206            // The activity manager only throws security exceptions, so let's
2207            // log all others.
2208            if (!(e instanceof SecurityException)) {
2209                Slog.wtf(TAG, "Activity Manager Crash", e);
2210            }
2211            throw e;
2212        }
2213    }
2214
2215    void updateCpuStats() {
2216        final long now = SystemClock.uptimeMillis();
2217        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2218            return;
2219        }
2220        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2221            synchronized (mProcessCpuThread) {
2222                mProcessCpuThread.notify();
2223            }
2224        }
2225    }
2226
2227    void updateCpuStatsNow() {
2228        synchronized (mProcessCpuThread) {
2229            mProcessCpuMutexFree.set(false);
2230            final long now = SystemClock.uptimeMillis();
2231            boolean haveNewCpuStats = false;
2232
2233            if (MONITOR_CPU_USAGE &&
2234                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2235                mLastCpuTime.set(now);
2236                haveNewCpuStats = true;
2237                mProcessCpuTracker.update();
2238                //Slog.i(TAG, mProcessCpu.printCurrentState());
2239                //Slog.i(TAG, "Total CPU usage: "
2240                //        + mProcessCpu.getTotalCpuPercent() + "%");
2241
2242                // Slog the cpu usage if the property is set.
2243                if ("true".equals(SystemProperties.get("events.cpu"))) {
2244                    int user = mProcessCpuTracker.getLastUserTime();
2245                    int system = mProcessCpuTracker.getLastSystemTime();
2246                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2247                    int irq = mProcessCpuTracker.getLastIrqTime();
2248                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2249                    int idle = mProcessCpuTracker.getLastIdleTime();
2250
2251                    int total = user + system + iowait + irq + softIrq + idle;
2252                    if (total == 0) total = 1;
2253
2254                    EventLog.writeEvent(EventLogTags.CPU,
2255                            ((user+system+iowait+irq+softIrq) * 100) / total,
2256                            (user * 100) / total,
2257                            (system * 100) / total,
2258                            (iowait * 100) / total,
2259                            (irq * 100) / total,
2260                            (softIrq * 100) / total);
2261                }
2262            }
2263
2264            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2265            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2266            synchronized(bstats) {
2267                synchronized(mPidsSelfLocked) {
2268                    if (haveNewCpuStats) {
2269                        if (mOnBattery) {
2270                            int perc = bstats.startAddingCpuLocked();
2271                            int totalUTime = 0;
2272                            int totalSTime = 0;
2273                            final int N = mProcessCpuTracker.countStats();
2274                            for (int i=0; i<N; i++) {
2275                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2276                                if (!st.working) {
2277                                    continue;
2278                                }
2279                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2280                                int otherUTime = (st.rel_utime*perc)/100;
2281                                int otherSTime = (st.rel_stime*perc)/100;
2282                                totalUTime += otherUTime;
2283                                totalSTime += otherSTime;
2284                                if (pr != null) {
2285                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2286                                    if (ps == null || !ps.isActive()) {
2287                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2288                                                pr.info.uid, pr.processName);
2289                                    }
2290                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2291                                            st.rel_stime-otherSTime);
2292                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2293                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2294                                } else {
2295                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2296                                    if (ps == null || !ps.isActive()) {
2297                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2298                                                bstats.mapUid(st.uid), st.name);
2299                                    }
2300                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2301                                            st.rel_stime-otherSTime);
2302                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2303                                }
2304                            }
2305                            bstats.finishAddingCpuLocked(perc, totalUTime,
2306                                    totalSTime, cpuSpeedTimes);
2307                        }
2308                    }
2309                }
2310
2311                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2312                    mLastWriteTime = now;
2313                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2314                }
2315            }
2316        }
2317    }
2318
2319    @Override
2320    public void batteryNeedsCpuUpdate() {
2321        updateCpuStatsNow();
2322    }
2323
2324    @Override
2325    public void batteryPowerChanged(boolean onBattery) {
2326        // When plugging in, update the CPU stats first before changing
2327        // the plug state.
2328        updateCpuStatsNow();
2329        synchronized (this) {
2330            synchronized(mPidsSelfLocked) {
2331                mOnBattery = DEBUG_POWER ? true : onBattery;
2332            }
2333        }
2334    }
2335
2336    /**
2337     * Initialize the application bind args. These are passed to each
2338     * process when the bindApplication() IPC is sent to the process. They're
2339     * lazily setup to make sure the services are running when they're asked for.
2340     */
2341    private HashMap<String, IBinder> getCommonServicesLocked() {
2342        if (mAppBindArgs == null) {
2343            mAppBindArgs = new HashMap<String, IBinder>();
2344
2345            // Setup the application init args
2346            mAppBindArgs.put("package", ServiceManager.getService("package"));
2347            mAppBindArgs.put("window", ServiceManager.getService("window"));
2348            mAppBindArgs.put(Context.ALARM_SERVICE,
2349                    ServiceManager.getService(Context.ALARM_SERVICE));
2350        }
2351        return mAppBindArgs;
2352    }
2353
2354    final void setFocusedActivityLocked(ActivityRecord r) {
2355        if (mFocusedActivity != r) {
2356            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2357            mFocusedActivity = r;
2358            if (r.task != null && r.task.voiceInteractor != null) {
2359                startRunningVoiceLocked();
2360            } else {
2361                finishRunningVoiceLocked();
2362            }
2363            mStackSupervisor.setFocusedStack(r);
2364            if (r != null) {
2365                mWindowManager.setFocusedApp(r.appToken, true);
2366            }
2367            applyUpdateLockStateLocked(r);
2368        }
2369    }
2370
2371    final void clearFocusedActivity(ActivityRecord r) {
2372        if (mFocusedActivity == r) {
2373            mFocusedActivity = null;
2374        }
2375    }
2376
2377    @Override
2378    public void setFocusedStack(int stackId) {
2379        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2380        synchronized (ActivityManagerService.this) {
2381            ActivityStack stack = mStackSupervisor.getStack(stackId);
2382            if (stack != null) {
2383                ActivityRecord r = stack.topRunningActivityLocked(null);
2384                if (r != null) {
2385                    setFocusedActivityLocked(r);
2386                }
2387            }
2388        }
2389    }
2390
2391    @Override
2392    public void notifyActivityDrawn(IBinder token) {
2393        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2394        synchronized (this) {
2395            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2396            if (r != null) {
2397                r.task.stack.notifyActivityDrawnLocked(r);
2398            }
2399        }
2400    }
2401
2402    final void applyUpdateLockStateLocked(ActivityRecord r) {
2403        // Modifications to the UpdateLock state are done on our handler, outside
2404        // the activity manager's locks.  The new state is determined based on the
2405        // state *now* of the relevant activity record.  The object is passed to
2406        // the handler solely for logging detail, not to be consulted/modified.
2407        final boolean nextState = r != null && r.immersive;
2408        mHandler.sendMessage(
2409                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2410    }
2411
2412    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2413        Message msg = Message.obtain();
2414        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2415        msg.obj = r.task.askedCompatMode ? null : r;
2416        mHandler.sendMessage(msg);
2417    }
2418
2419    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2420            String what, Object obj, ProcessRecord srcApp) {
2421        app.lastActivityTime = now;
2422
2423        if (app.activities.size() > 0) {
2424            // Don't want to touch dependent processes that are hosting activities.
2425            return index;
2426        }
2427
2428        int lrui = mLruProcesses.lastIndexOf(app);
2429        if (lrui < 0) {
2430            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2431                    + what + " " + obj + " from " + srcApp);
2432            return index;
2433        }
2434
2435        if (lrui >= index) {
2436            // Don't want to cause this to move dependent processes *back* in the
2437            // list as if they were less frequently used.
2438            return index;
2439        }
2440
2441        if (lrui >= mLruProcessActivityStart) {
2442            // Don't want to touch dependent processes that are hosting activities.
2443            return index;
2444        }
2445
2446        mLruProcesses.remove(lrui);
2447        if (index > 0) {
2448            index--;
2449        }
2450        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2451                + " in LRU list: " + app);
2452        mLruProcesses.add(index, app);
2453        return index;
2454    }
2455
2456    final void removeLruProcessLocked(ProcessRecord app) {
2457        int lrui = mLruProcesses.lastIndexOf(app);
2458        if (lrui >= 0) {
2459            if (lrui <= mLruProcessActivityStart) {
2460                mLruProcessActivityStart--;
2461            }
2462            if (lrui <= mLruProcessServiceStart) {
2463                mLruProcessServiceStart--;
2464            }
2465            mLruProcesses.remove(lrui);
2466        }
2467    }
2468
2469    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2470            ProcessRecord client) {
2471        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2472                || app.treatLikeActivity;
2473        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2474        if (!activityChange && hasActivity) {
2475            // The process has activities, so we are only allowing activity-based adjustments
2476            // to move it.  It should be kept in the front of the list with other
2477            // processes that have activities, and we don't want those to change their
2478            // order except due to activity operations.
2479            return;
2480        }
2481
2482        mLruSeq++;
2483        final long now = SystemClock.uptimeMillis();
2484        app.lastActivityTime = now;
2485
2486        // First a quick reject: if the app is already at the position we will
2487        // put it, then there is nothing to do.
2488        if (hasActivity) {
2489            final int N = mLruProcesses.size();
2490            if (N > 0 && mLruProcesses.get(N-1) == app) {
2491                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2492                return;
2493            }
2494        } else {
2495            if (mLruProcessServiceStart > 0
2496                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2497                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2498                return;
2499            }
2500        }
2501
2502        int lrui = mLruProcesses.lastIndexOf(app);
2503
2504        if (app.persistent && lrui >= 0) {
2505            // We don't care about the position of persistent processes, as long as
2506            // they are in the list.
2507            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2508            return;
2509        }
2510
2511        /* In progress: compute new position first, so we can avoid doing work
2512           if the process is not actually going to move.  Not yet working.
2513        int addIndex;
2514        int nextIndex;
2515        boolean inActivity = false, inService = false;
2516        if (hasActivity) {
2517            // Process has activities, put it at the very tipsy-top.
2518            addIndex = mLruProcesses.size();
2519            nextIndex = mLruProcessServiceStart;
2520            inActivity = true;
2521        } else if (hasService) {
2522            // Process has services, put it at the top of the service list.
2523            addIndex = mLruProcessActivityStart;
2524            nextIndex = mLruProcessServiceStart;
2525            inActivity = true;
2526            inService = true;
2527        } else  {
2528            // Process not otherwise of interest, it goes to the top of the non-service area.
2529            addIndex = mLruProcessServiceStart;
2530            if (client != null) {
2531                int clientIndex = mLruProcesses.lastIndexOf(client);
2532                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2533                        + app);
2534                if (clientIndex >= 0 && addIndex > clientIndex) {
2535                    addIndex = clientIndex;
2536                }
2537            }
2538            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2539        }
2540
2541        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2542                + mLruProcessActivityStart + "): " + app);
2543        */
2544
2545        if (lrui >= 0) {
2546            if (lrui < mLruProcessActivityStart) {
2547                mLruProcessActivityStart--;
2548            }
2549            if (lrui < mLruProcessServiceStart) {
2550                mLruProcessServiceStart--;
2551            }
2552            /*
2553            if (addIndex > lrui) {
2554                addIndex--;
2555            }
2556            if (nextIndex > lrui) {
2557                nextIndex--;
2558            }
2559            */
2560            mLruProcesses.remove(lrui);
2561        }
2562
2563        /*
2564        mLruProcesses.add(addIndex, app);
2565        if (inActivity) {
2566            mLruProcessActivityStart++;
2567        }
2568        if (inService) {
2569            mLruProcessActivityStart++;
2570        }
2571        */
2572
2573        int nextIndex;
2574        if (hasActivity) {
2575            final int N = mLruProcesses.size();
2576            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2577                // Process doesn't have activities, but has clients with
2578                // activities...  move it up, but one below the top (the top
2579                // should always have a real activity).
2580                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2581                mLruProcesses.add(N-1, app);
2582                // To keep it from spamming the LRU list (by making a bunch of clients),
2583                // we will push down any other entries owned by the app.
2584                final int uid = app.info.uid;
2585                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2586                    ProcessRecord subProc = mLruProcesses.get(i);
2587                    if (subProc.info.uid == uid) {
2588                        // We want to push this one down the list.  If the process after
2589                        // it is for the same uid, however, don't do so, because we don't
2590                        // want them internally to be re-ordered.
2591                        if (mLruProcesses.get(i-1).info.uid != uid) {
2592                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2593                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2594                            ProcessRecord tmp = mLruProcesses.get(i);
2595                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2596                            mLruProcesses.set(i-1, tmp);
2597                            i--;
2598                        }
2599                    } else {
2600                        // A gap, we can stop here.
2601                        break;
2602                    }
2603                }
2604            } else {
2605                // Process has activities, put it at the very tipsy-top.
2606                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2607                mLruProcesses.add(app);
2608            }
2609            nextIndex = mLruProcessServiceStart;
2610        } else if (hasService) {
2611            // Process has services, put it at the top of the service list.
2612            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2613            mLruProcesses.add(mLruProcessActivityStart, app);
2614            nextIndex = mLruProcessServiceStart;
2615            mLruProcessActivityStart++;
2616        } else  {
2617            // Process not otherwise of interest, it goes to the top of the non-service area.
2618            int index = mLruProcessServiceStart;
2619            if (client != null) {
2620                // If there is a client, don't allow the process to be moved up higher
2621                // in the list than that client.
2622                int clientIndex = mLruProcesses.lastIndexOf(client);
2623                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2624                        + " when updating " + app);
2625                if (clientIndex <= lrui) {
2626                    // Don't allow the client index restriction to push it down farther in the
2627                    // list than it already is.
2628                    clientIndex = lrui;
2629                }
2630                if (clientIndex >= 0 && index > clientIndex) {
2631                    index = clientIndex;
2632                }
2633            }
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2635            mLruProcesses.add(index, app);
2636            nextIndex = index-1;
2637            mLruProcessActivityStart++;
2638            mLruProcessServiceStart++;
2639        }
2640
2641        // If the app is currently using a content provider or service,
2642        // bump those processes as well.
2643        for (int j=app.connections.size()-1; j>=0; j--) {
2644            ConnectionRecord cr = app.connections.valueAt(j);
2645            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2646                    && cr.binding.service.app != null
2647                    && cr.binding.service.app.lruSeq != mLruSeq
2648                    && !cr.binding.service.app.persistent) {
2649                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2650                        "service connection", cr, app);
2651            }
2652        }
2653        for (int j=app.conProviders.size()-1; j>=0; j--) {
2654            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2655            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2656                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2657                        "provider reference", cpr, app);
2658            }
2659        }
2660    }
2661
2662    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2663        if (uid == Process.SYSTEM_UID) {
2664            // The system gets to run in any process.  If there are multiple
2665            // processes with the same uid, just pick the first (this
2666            // should never happen).
2667            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2668            if (procs == null) return null;
2669            final int N = procs.size();
2670            for (int i = 0; i < N; i++) {
2671                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2672            }
2673        }
2674        ProcessRecord proc = mProcessNames.get(processName, uid);
2675        if (false && proc != null && !keepIfLarge
2676                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2677                && proc.lastCachedPss >= 4000) {
2678            // Turn this condition on to cause killing to happen regularly, for testing.
2679            if (proc.baseProcessTracker != null) {
2680                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2681            }
2682            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2683                    + "k from cached");
2684        } else if (proc != null && !keepIfLarge
2685                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2686                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2687            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2688            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2689                if (proc.baseProcessTracker != null) {
2690                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2691                }
2692                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2693                        + "k from cached");
2694            }
2695        }
2696        return proc;
2697    }
2698
2699    void ensurePackageDexOpt(String packageName) {
2700        IPackageManager pm = AppGlobals.getPackageManager();
2701        try {
2702            if (pm.performDexOpt(packageName)) {
2703                mDidDexOpt = true;
2704            }
2705        } catch (RemoteException e) {
2706        }
2707    }
2708
2709    boolean isNextTransitionForward() {
2710        int transit = mWindowManager.getPendingAppTransition();
2711        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2712                || transit == AppTransition.TRANSIT_TASK_OPEN
2713                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2714    }
2715
2716    final ProcessRecord startProcessLocked(String processName,
2717            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2718            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2719            boolean isolated, boolean keepIfLarge) {
2720        ProcessRecord app;
2721        if (!isolated) {
2722            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2723        } else {
2724            // If this is an isolated process, it can't re-use an existing process.
2725            app = null;
2726        }
2727        // We don't have to do anything more if:
2728        // (1) There is an existing application record; and
2729        // (2) The caller doesn't think it is dead, OR there is no thread
2730        //     object attached to it so we know it couldn't have crashed; and
2731        // (3) There is a pid assigned to it, so it is either starting or
2732        //     already running.
2733        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2734                + " app=" + app + " knownToBeDead=" + knownToBeDead
2735                + " thread=" + (app != null ? app.thread : null)
2736                + " pid=" + (app != null ? app.pid : -1));
2737        if (app != null && app.pid > 0) {
2738            if (!knownToBeDead || app.thread == null) {
2739                // We already have the app running, or are waiting for it to
2740                // come up (we have a pid but not yet its thread), so keep it.
2741                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2742                // If this is a new package in the process, add the package to the list
2743                app.addPackage(info.packageName, mProcessStats);
2744                return app;
2745            }
2746
2747            // An application record is attached to a previous process,
2748            // clean it up now.
2749            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2750            handleAppDiedLocked(app, true, true);
2751        }
2752
2753        String hostingNameStr = hostingName != null
2754                ? hostingName.flattenToShortString() : null;
2755
2756        if (!isolated) {
2757            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2758                // If we are in the background, then check to see if this process
2759                // is bad.  If so, we will just silently fail.
2760                if (mBadProcesses.get(info.processName, info.uid) != null) {
2761                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2762                            + "/" + info.processName);
2763                    return null;
2764                }
2765            } else {
2766                // When the user is explicitly starting a process, then clear its
2767                // crash count so that we won't make it bad until they see at
2768                // least one crash dialog again, and make the process good again
2769                // if it had been bad.
2770                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2771                        + "/" + info.processName);
2772                mProcessCrashTimes.remove(info.processName, info.uid);
2773                if (mBadProcesses.get(info.processName, info.uid) != null) {
2774                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2775                            UserHandle.getUserId(info.uid), info.uid,
2776                            info.processName);
2777                    mBadProcesses.remove(info.processName, info.uid);
2778                    if (app != null) {
2779                        app.bad = false;
2780                    }
2781                }
2782            }
2783        }
2784
2785        if (app == null) {
2786            app = newProcessRecordLocked(info, processName, isolated);
2787            if (app == null) {
2788                Slog.w(TAG, "Failed making new process record for "
2789                        + processName + "/" + info.uid + " isolated=" + isolated);
2790                return null;
2791            }
2792            mProcessNames.put(processName, app.uid, app);
2793            if (isolated) {
2794                mIsolatedProcesses.put(app.uid, app);
2795            }
2796        } else {
2797            // If this is a new package in the process, add the package to the list
2798            app.addPackage(info.packageName, mProcessStats);
2799        }
2800
2801        // If the system is not ready yet, then hold off on starting this
2802        // process until it is.
2803        if (!mProcessesReady
2804                && !isAllowedWhileBooting(info)
2805                && !allowWhileBooting) {
2806            if (!mProcessesOnHold.contains(app)) {
2807                mProcessesOnHold.add(app);
2808            }
2809            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2810            return app;
2811        }
2812
2813        startProcessLocked(app, hostingType, hostingNameStr);
2814        return (app.pid != 0) ? app : null;
2815    }
2816
2817    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2818        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2819    }
2820
2821    private final void startProcessLocked(ProcessRecord app,
2822            String hostingType, String hostingNameStr) {
2823        if (app.pid > 0 && app.pid != MY_PID) {
2824            synchronized (mPidsSelfLocked) {
2825                mPidsSelfLocked.remove(app.pid);
2826                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2827            }
2828            app.setPid(0);
2829        }
2830
2831        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2832                "startProcessLocked removing on hold: " + app);
2833        mProcessesOnHold.remove(app);
2834
2835        updateCpuStats();
2836
2837        try {
2838            int uid = app.uid;
2839
2840            int[] gids = null;
2841            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2842            if (!app.isolated) {
2843                int[] permGids = null;
2844                try {
2845                    final PackageManager pm = mContext.getPackageManager();
2846                    permGids = pm.getPackageGids(app.info.packageName);
2847
2848                    if (Environment.isExternalStorageEmulated()) {
2849                        if (pm.checkPermission(
2850                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2851                                app.info.packageName) == PERMISSION_GRANTED) {
2852                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2853                        } else {
2854                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2855                        }
2856                    }
2857                } catch (PackageManager.NameNotFoundException e) {
2858                    Slog.w(TAG, "Unable to retrieve gids", e);
2859                }
2860
2861                /*
2862                 * Add shared application GID so applications can share some
2863                 * resources like shared libraries
2864                 */
2865                if (permGids == null) {
2866                    gids = new int[1];
2867                } else {
2868                    gids = new int[permGids.length + 1];
2869                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2870                }
2871                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2872            }
2873            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2874                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2875                        && mTopComponent != null
2876                        && app.processName.equals(mTopComponent.getPackageName())) {
2877                    uid = 0;
2878                }
2879                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2880                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2881                    uid = 0;
2882                }
2883            }
2884            int debugFlags = 0;
2885            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2886                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2887                // Also turn on CheckJNI for debuggable apps. It's quite
2888                // awkward to turn on otherwise.
2889                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2890            }
2891            // Run the app in safe mode if its manifest requests so or the
2892            // system is booted in safe mode.
2893            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2894                mSafeMode == true) {
2895                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2896            }
2897            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.assert"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2905            }
2906
2907            String requiredAbi = app.info.requiredCpuAbi;
2908            if (requiredAbi == null) {
2909                requiredAbi = Build.SUPPORTED_ABIS[0];
2910            }
2911
2912            // Start the process.  It will either succeed and return a result containing
2913            // the PID of the new process, or else throw a RuntimeException.
2914            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2915                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2916                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2917
2918            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2919            synchronized (bs) {
2920                if (bs.isOnBattery()) {
2921                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2922                }
2923            }
2924
2925            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2926                    UserHandle.getUserId(uid), startResult.pid, uid,
2927                    app.processName, hostingType,
2928                    hostingNameStr != null ? hostingNameStr : "");
2929
2930            if (app.persistent) {
2931                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2932            }
2933
2934            StringBuilder buf = mStringBuilder;
2935            buf.setLength(0);
2936            buf.append("Start proc ");
2937            buf.append(app.processName);
2938            buf.append(" for ");
2939            buf.append(hostingType);
2940            if (hostingNameStr != null) {
2941                buf.append(" ");
2942                buf.append(hostingNameStr);
2943            }
2944            buf.append(": pid=");
2945            buf.append(startResult.pid);
2946            buf.append(" uid=");
2947            buf.append(uid);
2948            buf.append(" gids={");
2949            if (gids != null) {
2950                for (int gi=0; gi<gids.length; gi++) {
2951                    if (gi != 0) buf.append(", ");
2952                    buf.append(gids[gi]);
2953
2954                }
2955            }
2956            buf.append("}");
2957            Slog.i(TAG, buf.toString());
2958            app.setPid(startResult.pid);
2959            app.usingWrapper = startResult.usingWrapper;
2960            app.removed = false;
2961            synchronized (mPidsSelfLocked) {
2962                this.mPidsSelfLocked.put(startResult.pid, app);
2963                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2964                msg.obj = app;
2965                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2966                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2967            }
2968            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2969                    app.processName, app.info.uid);
2970            if (app.isolated) {
2971                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2972            }
2973        } catch (RuntimeException e) {
2974            // XXX do better error recovery.
2975            app.setPid(0);
2976            Slog.e(TAG, "Failure starting process " + app.processName, e);
2977        }
2978    }
2979
2980    void updateUsageStats(ActivityRecord component, boolean resumed) {
2981        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2982        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2983        if (resumed) {
2984            mUsageStatsService.noteResumeComponent(component.realActivity);
2985            synchronized (stats) {
2986                stats.noteActivityResumedLocked(component.app.uid);
2987            }
2988        } else {
2989            mUsageStatsService.notePauseComponent(component.realActivity);
2990            synchronized (stats) {
2991                stats.noteActivityPausedLocked(component.app.uid);
2992            }
2993        }
2994    }
2995
2996    Intent getHomeIntent() {
2997        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2998        intent.setComponent(mTopComponent);
2999        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3000            intent.addCategory(Intent.CATEGORY_HOME);
3001        }
3002        return intent;
3003    }
3004
3005    boolean startHomeActivityLocked(int userId) {
3006        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3007                && mTopAction == null) {
3008            // We are running in factory test mode, but unable to find
3009            // the factory test app, so just sit around displaying the
3010            // error message and don't try to start anything.
3011            return false;
3012        }
3013        Intent intent = getHomeIntent();
3014        ActivityInfo aInfo =
3015            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3016        if (aInfo != null) {
3017            intent.setComponent(new ComponentName(
3018                    aInfo.applicationInfo.packageName, aInfo.name));
3019            // Don't do this if the home app is currently being
3020            // instrumented.
3021            aInfo = new ActivityInfo(aInfo);
3022            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3023            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3024                    aInfo.applicationInfo.uid, true);
3025            if (app == null || app.instrumentationClass == null) {
3026                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3027                mStackSupervisor.startHomeActivity(intent, aInfo);
3028            }
3029        }
3030
3031        return true;
3032    }
3033
3034    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3035        ActivityInfo ai = null;
3036        ComponentName comp = intent.getComponent();
3037        try {
3038            if (comp != null) {
3039                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3040            } else {
3041                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3042                        intent,
3043                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3044                            flags, userId);
3045
3046                if (info != null) {
3047                    ai = info.activityInfo;
3048                }
3049            }
3050        } catch (RemoteException e) {
3051            // ignore
3052        }
3053
3054        return ai;
3055    }
3056
3057    /**
3058     * Starts the "new version setup screen" if appropriate.
3059     */
3060    void startSetupActivityLocked() {
3061        // Only do this once per boot.
3062        if (mCheckedForSetup) {
3063            return;
3064        }
3065
3066        // We will show this screen if the current one is a different
3067        // version than the last one shown, and we are not running in
3068        // low-level factory test mode.
3069        final ContentResolver resolver = mContext.getContentResolver();
3070        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3071                Settings.Global.getInt(resolver,
3072                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3073            mCheckedForSetup = true;
3074
3075            // See if we should be showing the platform update setup UI.
3076            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3077            List<ResolveInfo> ris = mContext.getPackageManager()
3078                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3079
3080            // We don't allow third party apps to replace this.
3081            ResolveInfo ri = null;
3082            for (int i=0; ris != null && i<ris.size(); i++) {
3083                if ((ris.get(i).activityInfo.applicationInfo.flags
3084                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3085                    ri = ris.get(i);
3086                    break;
3087                }
3088            }
3089
3090            if (ri != null) {
3091                String vers = ri.activityInfo.metaData != null
3092                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3093                        : null;
3094                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3095                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3096                            Intent.METADATA_SETUP_VERSION);
3097                }
3098                String lastVers = Settings.Secure.getString(
3099                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3100                if (vers != null && !vers.equals(lastVers)) {
3101                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3102                    intent.setComponent(new ComponentName(
3103                            ri.activityInfo.packageName, ri.activityInfo.name));
3104                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3105                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3106                }
3107            }
3108        }
3109    }
3110
3111    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3112        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3113    }
3114
3115    void enforceNotIsolatedCaller(String caller) {
3116        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3117            throw new SecurityException("Isolated process not allowed to call " + caller);
3118        }
3119    }
3120
3121    @Override
3122    public int getFrontActivityScreenCompatMode() {
3123        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3124        synchronized (this) {
3125            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3126        }
3127    }
3128
3129    @Override
3130    public void setFrontActivityScreenCompatMode(int mode) {
3131        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3132                "setFrontActivityScreenCompatMode");
3133        synchronized (this) {
3134            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3135        }
3136    }
3137
3138    @Override
3139    public int getPackageScreenCompatMode(String packageName) {
3140        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3141        synchronized (this) {
3142            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3143        }
3144    }
3145
3146    @Override
3147    public void setPackageScreenCompatMode(String packageName, int mode) {
3148        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3149                "setPackageScreenCompatMode");
3150        synchronized (this) {
3151            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3152        }
3153    }
3154
3155    @Override
3156    public boolean getPackageAskScreenCompat(String packageName) {
3157        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3158        synchronized (this) {
3159            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3160        }
3161    }
3162
3163    @Override
3164    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3166                "setPackageAskScreenCompat");
3167        synchronized (this) {
3168            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3169        }
3170    }
3171
3172    private void dispatchProcessesChanged() {
3173        int N;
3174        synchronized (this) {
3175            N = mPendingProcessChanges.size();
3176            if (mActiveProcessChanges.length < N) {
3177                mActiveProcessChanges = new ProcessChangeItem[N];
3178            }
3179            mPendingProcessChanges.toArray(mActiveProcessChanges);
3180            mAvailProcessChanges.addAll(mPendingProcessChanges);
3181            mPendingProcessChanges.clear();
3182            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3183        }
3184
3185        int i = mProcessObservers.beginBroadcast();
3186        while (i > 0) {
3187            i--;
3188            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3189            if (observer != null) {
3190                try {
3191                    for (int j=0; j<N; j++) {
3192                        ProcessChangeItem item = mActiveProcessChanges[j];
3193                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3194                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3195                                    + item.pid + " uid=" + item.uid + ": "
3196                                    + item.foregroundActivities);
3197                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3198                                    item.foregroundActivities);
3199                        }
3200                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3201                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3202                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3203                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3204                        }
3205                    }
3206                } catch (RemoteException e) {
3207                }
3208            }
3209        }
3210        mProcessObservers.finishBroadcast();
3211    }
3212
3213    private void dispatchProcessDied(int pid, int uid) {
3214        int i = mProcessObservers.beginBroadcast();
3215        while (i > 0) {
3216            i--;
3217            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3218            if (observer != null) {
3219                try {
3220                    observer.onProcessDied(pid, uid);
3221                } catch (RemoteException e) {
3222                }
3223            }
3224        }
3225        mProcessObservers.finishBroadcast();
3226    }
3227
3228    final void doPendingActivityLaunchesLocked(boolean doResume) {
3229        final int N = mPendingActivityLaunches.size();
3230        if (N <= 0) {
3231            return;
3232        }
3233        for (int i=0; i<N; i++) {
3234            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3235            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3236                    doResume && i == (N-1), null);
3237        }
3238        mPendingActivityLaunches.clear();
3239    }
3240
3241    @Override
3242    public final int startActivity(IApplicationThread caller, String callingPackage,
3243            Intent intent, String resolvedType, IBinder resultTo,
3244            String resultWho, int requestCode, int startFlags,
3245            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3246        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3247                resultWho, requestCode,
3248                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3249    }
3250
3251    @Override
3252    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3253            Intent intent, String resolvedType, IBinder resultTo,
3254            String resultWho, int requestCode, int startFlags,
3255            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3256        enforceNotIsolatedCaller("startActivity");
3257        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3258                false, true, "startActivity", null);
3259        // TODO: Switch to user app stacks here.
3260        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3261                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3262                null, null, options, userId, null);
3263    }
3264
3265    @Override
3266    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3267            Intent intent, String resolvedType, IBinder resultTo,
3268            String resultWho, int requestCode, int startFlags, String profileFile,
3269            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3270        enforceNotIsolatedCaller("startActivityAndWait");
3271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3272                false, true, "startActivityAndWait", null);
3273        WaitResult res = new WaitResult();
3274        // TODO: Switch to user app stacks here.
3275        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3276                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3277                res, null, options, UserHandle.getCallingUserId(), null);
3278        return res;
3279    }
3280
3281    @Override
3282    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3283            Intent intent, String resolvedType, IBinder resultTo,
3284            String resultWho, int requestCode, int startFlags, Configuration config,
3285            Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivityWithConfig");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, true, "startActivityWithConfig", null);
3289        // TODO: Switch to user app stacks here.
3290        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3291                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3292                null, null, null, config, options, userId, null);
3293        return ret;
3294    }
3295
3296    @Override
3297    public int startActivityIntentSender(IApplicationThread caller,
3298            IntentSender intent, Intent fillInIntent, String resolvedType,
3299            IBinder resultTo, String resultWho, int requestCode,
3300            int flagsMask, int flagsValues, Bundle options) {
3301        enforceNotIsolatedCaller("startActivityIntentSender");
3302        // Refuse possible leaked file descriptors
3303        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3304            throw new IllegalArgumentException("File descriptors passed in Intent");
3305        }
3306
3307        IIntentSender sender = intent.getTarget();
3308        if (!(sender instanceof PendingIntentRecord)) {
3309            throw new IllegalArgumentException("Bad PendingIntent object");
3310        }
3311
3312        PendingIntentRecord pir = (PendingIntentRecord)sender;
3313
3314        synchronized (this) {
3315            // If this is coming from the currently resumed activity, it is
3316            // effectively saying that app switches are allowed at this point.
3317            final ActivityStack stack = getFocusedStack();
3318            if (stack.mResumedActivity != null &&
3319                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3320                mAppSwitchesAllowedTime = 0;
3321            }
3322        }
3323        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3324                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3325        return ret;
3326    }
3327
3328    @Override
3329    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3330            Intent intent, String resolvedType, IVoiceInteractionSession session,
3331            IVoiceInteractor interactor, int startFlags, String profileFile,
3332            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3333        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3334                != PackageManager.PERMISSION_GRANTED) {
3335            String msg = "Permission Denial: startVoiceActivity() from pid="
3336                    + Binder.getCallingPid()
3337                    + ", uid=" + Binder.getCallingUid()
3338                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3339            Slog.w(TAG, msg);
3340            throw new SecurityException(msg);
3341        }
3342        if (session == null || interactor == null) {
3343            throw new NullPointerException("null session or interactor");
3344        }
3345        userId = handleIncomingUser(callingPid, callingUid, userId,
3346                false, true, "startVoiceActivity", null);
3347        // TODO: Switch to user app stacks here.
3348        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3349                resolvedType, session, interactor, null, null, 0, startFlags,
3350                profileFile, profileFd, null, null, options, userId, null);
3351    }
3352
3353    @Override
3354    public boolean startNextMatchingActivity(IBinder callingActivity,
3355            Intent intent, Bundle options) {
3356        // Refuse possible leaked file descriptors
3357        if (intent != null && intent.hasFileDescriptors() == true) {
3358            throw new IllegalArgumentException("File descriptors passed in Intent");
3359        }
3360
3361        synchronized (this) {
3362            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3363            if (r == null) {
3364                ActivityOptions.abort(options);
3365                return false;
3366            }
3367            if (r.app == null || r.app.thread == null) {
3368                // The caller is not running...  d'oh!
3369                ActivityOptions.abort(options);
3370                return false;
3371            }
3372            intent = new Intent(intent);
3373            // The caller is not allowed to change the data.
3374            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3375            // And we are resetting to find the next component...
3376            intent.setComponent(null);
3377
3378            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3379
3380            ActivityInfo aInfo = null;
3381            try {
3382                List<ResolveInfo> resolves =
3383                    AppGlobals.getPackageManager().queryIntentActivities(
3384                            intent, r.resolvedType,
3385                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3386                            UserHandle.getCallingUserId());
3387
3388                // Look for the original activity in the list...
3389                final int N = resolves != null ? resolves.size() : 0;
3390                for (int i=0; i<N; i++) {
3391                    ResolveInfo rInfo = resolves.get(i);
3392                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3393                            && rInfo.activityInfo.name.equals(r.info.name)) {
3394                        // We found the current one...  the next matching is
3395                        // after it.
3396                        i++;
3397                        if (i<N) {
3398                            aInfo = resolves.get(i).activityInfo;
3399                        }
3400                        if (debug) {
3401                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3402                                    + "/" + r.info.name);
3403                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3404                                    + "/" + aInfo.name);
3405                        }
3406                        break;
3407                    }
3408                }
3409            } catch (RemoteException e) {
3410            }
3411
3412            if (aInfo == null) {
3413                // Nobody who is next!
3414                ActivityOptions.abort(options);
3415                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3416                return false;
3417            }
3418
3419            intent.setComponent(new ComponentName(
3420                    aInfo.applicationInfo.packageName, aInfo.name));
3421            intent.setFlags(intent.getFlags()&~(
3422                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3423                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3424                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3425                    Intent.FLAG_ACTIVITY_NEW_TASK));
3426
3427            // Okay now we need to start the new activity, replacing the
3428            // currently running activity.  This is a little tricky because
3429            // we want to start the new one as if the current one is finished,
3430            // but not finish the current one first so that there is no flicker.
3431            // And thus...
3432            final boolean wasFinishing = r.finishing;
3433            r.finishing = true;
3434
3435            // Propagate reply information over to the new activity.
3436            final ActivityRecord resultTo = r.resultTo;
3437            final String resultWho = r.resultWho;
3438            final int requestCode = r.requestCode;
3439            r.resultTo = null;
3440            if (resultTo != null) {
3441                resultTo.removeResultsLocked(r, resultWho, requestCode);
3442            }
3443
3444            final long origId = Binder.clearCallingIdentity();
3445            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3446                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3447                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3448                    options, false, null, null);
3449            Binder.restoreCallingIdentity(origId);
3450
3451            r.finishing = wasFinishing;
3452            if (res != ActivityManager.START_SUCCESS) {
3453                return false;
3454            }
3455            return true;
3456        }
3457    }
3458
3459    final int startActivityInPackage(int uid, String callingPackage,
3460            Intent intent, String resolvedType, IBinder resultTo,
3461            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3462                    IActivityContainer container) {
3463
3464        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3465                false, true, "startActivityInPackage", null);
3466
3467        // TODO: Switch to user app stacks here.
3468        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3469                null, null, resultTo, resultWho, requestCode, startFlags,
3470                null, null, null, null, options, userId, container);
3471        return ret;
3472    }
3473
3474    @Override
3475    public final int startActivities(IApplicationThread caller, String callingPackage,
3476            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3477            int userId) {
3478        enforceNotIsolatedCaller("startActivities");
3479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3480                false, true, "startActivity", null);
3481        // TODO: Switch to user app stacks here.
3482        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3483                resolvedTypes, resultTo, options, userId);
3484        return ret;
3485    }
3486
3487    final int startActivitiesInPackage(int uid, String callingPackage,
3488            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3489            Bundle options, int userId) {
3490
3491        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3492                false, true, "startActivityInPackage", null);
3493        // TODO: Switch to user app stacks here.
3494        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3495                resultTo, options, userId);
3496        return ret;
3497    }
3498
3499    final void addRecentTaskLocked(TaskRecord task) {
3500        int N = mRecentTasks.size();
3501        // Quick case: check if the top-most recent task is the same.
3502        if (N > 0 && mRecentTasks.get(0) == task) {
3503            return;
3504        }
3505        // Another quick case: never add voice sessions.
3506        if (task.voiceSession != null) {
3507            return;
3508        }
3509        // Remove any existing entries that are the same kind of task.
3510        final Intent intent = task.intent;
3511        final boolean document = intent != null && intent.isDocument();
3512        for (int i=0; i<N; i++) {
3513            TaskRecord tr = mRecentTasks.get(i);
3514            if (task != tr) {
3515                if (task.userId != tr.userId) {
3516                    continue;
3517                }
3518                final Intent trIntent = tr.intent;
3519                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3520                    (intent == null || !intent.filterEquals(trIntent))) {
3521                    continue;
3522                }
3523                if (document || trIntent != null && trIntent.isDocument()) {
3524                    // Document tasks do not match other tasks.
3525                    continue;
3526                }
3527            }
3528
3529            // Either task and tr are the same or, their affinities match or their intents match
3530            // and neither of them is a document.
3531            tr.disposeThumbnail();
3532            mRecentTasks.remove(i);
3533            i--;
3534            N--;
3535            if (task.intent == null) {
3536                // If the new recent task we are adding is not fully
3537                // specified, then replace it with the existing recent task.
3538                task = tr;
3539            }
3540        }
3541        if (N >= MAX_RECENT_TASKS) {
3542            mRecentTasks.remove(N-1).disposeThumbnail();
3543        }
3544        mRecentTasks.add(0, task);
3545    }
3546
3547    @Override
3548    public void reportActivityFullyDrawn(IBinder token) {
3549        synchronized (this) {
3550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3551            if (r == null) {
3552                return;
3553            }
3554            r.reportFullyDrawnLocked();
3555        }
3556    }
3557
3558    @Override
3559    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3560        synchronized (this) {
3561            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3562            if (r == null) {
3563                return;
3564            }
3565            final long origId = Binder.clearCallingIdentity();
3566            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3567            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3568                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3569            if (config != null) {
3570                r.frozenBeforeDestroy = true;
3571                if (!updateConfigurationLocked(config, r, false, false)) {
3572                    mStackSupervisor.resumeTopActivitiesLocked();
3573                }
3574            }
3575            Binder.restoreCallingIdentity(origId);
3576        }
3577    }
3578
3579    @Override
3580    public int getRequestedOrientation(IBinder token) {
3581        synchronized (this) {
3582            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3583            if (r == null) {
3584                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3585            }
3586            return mWindowManager.getAppOrientation(r.appToken);
3587        }
3588    }
3589
3590    /**
3591     * This is the internal entry point for handling Activity.finish().
3592     *
3593     * @param token The Binder token referencing the Activity we want to finish.
3594     * @param resultCode Result code, if any, from this Activity.
3595     * @param resultData Result data (Intent), if any, from this Activity.
3596     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3597     *            the root Activity in the task.
3598     *
3599     * @return Returns true if the activity successfully finished, or false if it is still running.
3600     */
3601    @Override
3602    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3603            boolean finishTask) {
3604        // Refuse possible leaked file descriptors
3605        if (resultData != null && resultData.hasFileDescriptors() == true) {
3606            throw new IllegalArgumentException("File descriptors passed in Intent");
3607        }
3608
3609        synchronized(this) {
3610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3611            if (r == null) {
3612                return true;
3613            }
3614            // Keep track of the root activity of the task before we finish it
3615            TaskRecord tr = r.task;
3616            ActivityRecord rootR = tr.getRootActivity();
3617            if (mController != null) {
3618                // Find the first activity that is not finishing.
3619                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3620                if (next != null) {
3621                    // ask watcher if this is allowed
3622                    boolean resumeOK = true;
3623                    try {
3624                        resumeOK = mController.activityResuming(next.packageName);
3625                    } catch (RemoteException e) {
3626                        mController = null;
3627                        Watchdog.getInstance().setActivityController(null);
3628                    }
3629
3630                    if (!resumeOK) {
3631                        return false;
3632                    }
3633                }
3634            }
3635            final long origId = Binder.clearCallingIdentity();
3636            try {
3637                boolean res;
3638                if (finishTask && r == rootR) {
3639                    // If requested, remove the task that is associated to this activity only if it
3640                    // was the root activity in the task.  The result code and data is ignored because
3641                    // we don't support returning them across task boundaries.
3642                    res = removeTaskByIdLocked(tr.taskId, 0);
3643                } else {
3644                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3645                            resultData, "app-request", true);
3646                }
3647                return res;
3648            } finally {
3649                Binder.restoreCallingIdentity(origId);
3650            }
3651        }
3652    }
3653
3654    @Override
3655    public final void finishHeavyWeightApp() {
3656        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3657                != PackageManager.PERMISSION_GRANTED) {
3658            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3659                    + Binder.getCallingPid()
3660                    + ", uid=" + Binder.getCallingUid()
3661                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3662            Slog.w(TAG, msg);
3663            throw new SecurityException(msg);
3664        }
3665
3666        synchronized(this) {
3667            if (mHeavyWeightProcess == null) {
3668                return;
3669            }
3670
3671            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3672                    mHeavyWeightProcess.activities);
3673            for (int i=0; i<activities.size(); i++) {
3674                ActivityRecord r = activities.get(i);
3675                if (!r.finishing) {
3676                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3677                            null, "finish-heavy", true);
3678                }
3679            }
3680
3681            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3682                    mHeavyWeightProcess.userId, 0));
3683            mHeavyWeightProcess = null;
3684        }
3685    }
3686
3687    @Override
3688    public void crashApplication(int uid, int initialPid, String packageName,
3689            String message) {
3690        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3691                != PackageManager.PERMISSION_GRANTED) {
3692            String msg = "Permission Denial: crashApplication() from pid="
3693                    + Binder.getCallingPid()
3694                    + ", uid=" + Binder.getCallingUid()
3695                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3696            Slog.w(TAG, msg);
3697            throw new SecurityException(msg);
3698        }
3699
3700        synchronized(this) {
3701            ProcessRecord proc = null;
3702
3703            // Figure out which process to kill.  We don't trust that initialPid
3704            // still has any relation to current pids, so must scan through the
3705            // list.
3706            synchronized (mPidsSelfLocked) {
3707                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3708                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3709                    if (p.uid != uid) {
3710                        continue;
3711                    }
3712                    if (p.pid == initialPid) {
3713                        proc = p;
3714                        break;
3715                    }
3716                    if (p.pkgList.containsKey(packageName)) {
3717                        proc = p;
3718                    }
3719                }
3720            }
3721
3722            if (proc == null) {
3723                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3724                        + " initialPid=" + initialPid
3725                        + " packageName=" + packageName);
3726                return;
3727            }
3728
3729            if (proc.thread != null) {
3730                if (proc.pid == Process.myPid()) {
3731                    Log.w(TAG, "crashApplication: trying to crash self!");
3732                    return;
3733                }
3734                long ident = Binder.clearCallingIdentity();
3735                try {
3736                    proc.thread.scheduleCrash(message);
3737                } catch (RemoteException e) {
3738                }
3739                Binder.restoreCallingIdentity(ident);
3740            }
3741        }
3742    }
3743
3744    @Override
3745    public final void finishSubActivity(IBinder token, String resultWho,
3746            int requestCode) {
3747        synchronized(this) {
3748            final long origId = Binder.clearCallingIdentity();
3749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3750            if (r != null) {
3751                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3752            }
3753            Binder.restoreCallingIdentity(origId);
3754        }
3755    }
3756
3757    @Override
3758    public boolean finishActivityAffinity(IBinder token) {
3759        synchronized(this) {
3760            final long origId = Binder.clearCallingIdentity();
3761            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3762            boolean res = false;
3763            if (r != null) {
3764                res = r.task.stack.finishActivityAffinityLocked(r);
3765            }
3766            Binder.restoreCallingIdentity(origId);
3767            return res;
3768        }
3769    }
3770
3771    @Override
3772    public boolean willActivityBeVisible(IBinder token) {
3773        synchronized(this) {
3774            ActivityStack stack = ActivityRecord.getStackLocked(token);
3775            if (stack != null) {
3776                return stack.willActivityBeVisibleLocked(token);
3777            }
3778            return false;
3779        }
3780    }
3781
3782    @Override
3783    public void overridePendingTransition(IBinder token, String packageName,
3784            int enterAnim, int exitAnim) {
3785        synchronized(this) {
3786            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3787            if (self == null) {
3788                return;
3789            }
3790
3791            final long origId = Binder.clearCallingIdentity();
3792
3793            if (self.state == ActivityState.RESUMED
3794                    || self.state == ActivityState.PAUSING) {
3795                mWindowManager.overridePendingAppTransition(packageName,
3796                        enterAnim, exitAnim, null);
3797            }
3798
3799            Binder.restoreCallingIdentity(origId);
3800        }
3801    }
3802
3803    /**
3804     * Main function for removing an existing process from the activity manager
3805     * as a result of that process going away.  Clears out all connections
3806     * to the process.
3807     */
3808    private final void handleAppDiedLocked(ProcessRecord app,
3809            boolean restarting, boolean allowRestart) {
3810        int pid = app.pid;
3811        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3812        if (!restarting) {
3813            removeLruProcessLocked(app);
3814            if (pid > 0) {
3815                ProcessList.remove(pid);
3816            }
3817        }
3818
3819        if (mProfileProc == app) {
3820            clearProfilerLocked();
3821        }
3822
3823        // Remove this application's activities from active lists.
3824        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3825
3826        app.activities.clear();
3827
3828        if (app.instrumentationClass != null) {
3829            Slog.w(TAG, "Crash of app " + app.processName
3830                  + " running instrumentation " + app.instrumentationClass);
3831            Bundle info = new Bundle();
3832            info.putString("shortMsg", "Process crashed.");
3833            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3834        }
3835
3836        if (!restarting) {
3837            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3838                // If there was nothing to resume, and we are not already
3839                // restarting this process, but there is a visible activity that
3840                // is hosted by the process...  then make sure all visible
3841                // activities are running, taking care of restarting this
3842                // process.
3843                if (hasVisibleActivities) {
3844                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3845                }
3846            }
3847        }
3848    }
3849
3850    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3851        IBinder threadBinder = thread.asBinder();
3852        // Find the application record.
3853        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3854            ProcessRecord rec = mLruProcesses.get(i);
3855            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3856                return i;
3857            }
3858        }
3859        return -1;
3860    }
3861
3862    final ProcessRecord getRecordForAppLocked(
3863            IApplicationThread thread) {
3864        if (thread == null) {
3865            return null;
3866        }
3867
3868        int appIndex = getLRURecordIndexForAppLocked(thread);
3869        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3870    }
3871
3872    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3873        // If there are no longer any background processes running,
3874        // and the app that died was not running instrumentation,
3875        // then tell everyone we are now low on memory.
3876        boolean haveBg = false;
3877        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3878            ProcessRecord rec = mLruProcesses.get(i);
3879            if (rec.thread != null
3880                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3881                haveBg = true;
3882                break;
3883            }
3884        }
3885
3886        if (!haveBg) {
3887            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3888            if (doReport) {
3889                long now = SystemClock.uptimeMillis();
3890                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3891                    doReport = false;
3892                } else {
3893                    mLastMemUsageReportTime = now;
3894                }
3895            }
3896            final ArrayList<ProcessMemInfo> memInfos
3897                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3898            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3899            long now = SystemClock.uptimeMillis();
3900            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3901                ProcessRecord rec = mLruProcesses.get(i);
3902                if (rec == dyingProc || rec.thread == null) {
3903                    continue;
3904                }
3905                if (doReport) {
3906                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3907                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3908                }
3909                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3910                    // The low memory report is overriding any current
3911                    // state for a GC request.  Make sure to do
3912                    // heavy/important/visible/foreground processes first.
3913                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3914                        rec.lastRequestedGc = 0;
3915                    } else {
3916                        rec.lastRequestedGc = rec.lastLowMemory;
3917                    }
3918                    rec.reportLowMemory = true;
3919                    rec.lastLowMemory = now;
3920                    mProcessesToGc.remove(rec);
3921                    addProcessToGcListLocked(rec);
3922                }
3923            }
3924            if (doReport) {
3925                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3926                mHandler.sendMessage(msg);
3927            }
3928            scheduleAppGcsLocked();
3929        }
3930    }
3931
3932    final void appDiedLocked(ProcessRecord app, int pid,
3933            IApplicationThread thread) {
3934
3935        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3936        synchronized (stats) {
3937            stats.noteProcessDiedLocked(app.info.uid, pid);
3938        }
3939
3940        // Clean up already done if the process has been re-started.
3941        if (app.pid == pid && app.thread != null &&
3942                app.thread.asBinder() == thread.asBinder()) {
3943            boolean doLowMem = app.instrumentationClass == null;
3944            boolean doOomAdj = doLowMem;
3945            if (!app.killedByAm) {
3946                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3947                        + ") has died.");
3948                mAllowLowerMemLevel = true;
3949            } else {
3950                // Note that we always want to do oom adj to update our state with the
3951                // new number of procs.
3952                mAllowLowerMemLevel = false;
3953                doLowMem = false;
3954            }
3955            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3956            if (DEBUG_CLEANUP) Slog.v(
3957                TAG, "Dying app: " + app + ", pid: " + pid
3958                + ", thread: " + thread.asBinder());
3959            handleAppDiedLocked(app, false, true);
3960
3961            if (doOomAdj) {
3962                updateOomAdjLocked();
3963            }
3964            if (doLowMem) {
3965                doLowMemReportIfNeededLocked(app);
3966            }
3967        } else if (app.pid != pid) {
3968            // A new process has already been started.
3969            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3970                    + ") has died and restarted (pid " + app.pid + ").");
3971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3972        } else if (DEBUG_PROCESSES) {
3973            Slog.d(TAG, "Received spurious death notification for thread "
3974                    + thread.asBinder());
3975        }
3976    }
3977
3978    /**
3979     * If a stack trace dump file is configured, dump process stack traces.
3980     * @param clearTraces causes the dump file to be erased prior to the new
3981     *    traces being written, if true; when false, the new traces will be
3982     *    appended to any existing file content.
3983     * @param firstPids of dalvik VM processes to dump stack traces for first
3984     * @param lastPids of dalvik VM processes to dump stack traces for last
3985     * @param nativeProcs optional list of native process names to dump stack crawls
3986     * @return file containing stack traces, or null if no dump file is configured
3987     */
3988    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3989            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3990        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3991        if (tracesPath == null || tracesPath.length() == 0) {
3992            return null;
3993        }
3994
3995        File tracesFile = new File(tracesPath);
3996        try {
3997            File tracesDir = tracesFile.getParentFile();
3998            if (!tracesDir.exists()) {
3999                tracesFile.mkdirs();
4000                if (!SELinux.restorecon(tracesDir)) {
4001                    return null;
4002                }
4003            }
4004            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4005
4006            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4007            tracesFile.createNewFile();
4008            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4009        } catch (IOException e) {
4010            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4011            return null;
4012        }
4013
4014        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4015        return tracesFile;
4016    }
4017
4018    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4019            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4020        // Use a FileObserver to detect when traces finish writing.
4021        // The order of traces is considered important to maintain for legibility.
4022        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4023            @Override
4024            public synchronized void onEvent(int event, String path) { notify(); }
4025        };
4026
4027        try {
4028            observer.startWatching();
4029
4030            // First collect all of the stacks of the most important pids.
4031            if (firstPids != null) {
4032                try {
4033                    int num = firstPids.size();
4034                    for (int i = 0; i < num; i++) {
4035                        synchronized (observer) {
4036                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4037                            observer.wait(200);  // Wait for write-close, give up after 200msec
4038                        }
4039                    }
4040                } catch (InterruptedException e) {
4041                    Log.wtf(TAG, e);
4042                }
4043            }
4044
4045            // Next collect the stacks of the native pids
4046            if (nativeProcs != null) {
4047                int[] pids = Process.getPidsForCommands(nativeProcs);
4048                if (pids != null) {
4049                    for (int pid : pids) {
4050                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4051                    }
4052                }
4053            }
4054
4055            // Lastly, measure CPU usage.
4056            if (processCpuTracker != null) {
4057                processCpuTracker.init();
4058                System.gc();
4059                processCpuTracker.update();
4060                try {
4061                    synchronized (processCpuTracker) {
4062                        processCpuTracker.wait(500); // measure over 1/2 second.
4063                    }
4064                } catch (InterruptedException e) {
4065                }
4066                processCpuTracker.update();
4067
4068                // We'll take the stack crawls of just the top apps using CPU.
4069                final int N = processCpuTracker.countWorkingStats();
4070                int numProcs = 0;
4071                for (int i=0; i<N && numProcs<5; i++) {
4072                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4073                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4074                        numProcs++;
4075                        try {
4076                            synchronized (observer) {
4077                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4078                                observer.wait(200);  // Wait for write-close, give up after 200msec
4079                            }
4080                        } catch (InterruptedException e) {
4081                            Log.wtf(TAG, e);
4082                        }
4083
4084                    }
4085                }
4086            }
4087        } finally {
4088            observer.stopWatching();
4089        }
4090    }
4091
4092    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4093        if (true || IS_USER_BUILD) {
4094            return;
4095        }
4096        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4097        if (tracesPath == null || tracesPath.length() == 0) {
4098            return;
4099        }
4100
4101        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4102        StrictMode.allowThreadDiskWrites();
4103        try {
4104            final File tracesFile = new File(tracesPath);
4105            final File tracesDir = tracesFile.getParentFile();
4106            final File tracesTmp = new File(tracesDir, "__tmp__");
4107            try {
4108                if (!tracesDir.exists()) {
4109                    tracesFile.mkdirs();
4110                    if (!SELinux.restorecon(tracesDir.getPath())) {
4111                        return;
4112                    }
4113                }
4114                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4115
4116                if (tracesFile.exists()) {
4117                    tracesTmp.delete();
4118                    tracesFile.renameTo(tracesTmp);
4119                }
4120                StringBuilder sb = new StringBuilder();
4121                Time tobj = new Time();
4122                tobj.set(System.currentTimeMillis());
4123                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4124                sb.append(": ");
4125                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4126                sb.append(" since ");
4127                sb.append(msg);
4128                FileOutputStream fos = new FileOutputStream(tracesFile);
4129                fos.write(sb.toString().getBytes());
4130                if (app == null) {
4131                    fos.write("\n*** No application process!".getBytes());
4132                }
4133                fos.close();
4134                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4135            } catch (IOException e) {
4136                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4137                return;
4138            }
4139
4140            if (app != null) {
4141                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4142                firstPids.add(app.pid);
4143                dumpStackTraces(tracesPath, firstPids, null, null, null);
4144            }
4145
4146            File lastTracesFile = null;
4147            File curTracesFile = null;
4148            for (int i=9; i>=0; i--) {
4149                String name = String.format(Locale.US, "slow%02d.txt", i);
4150                curTracesFile = new File(tracesDir, name);
4151                if (curTracesFile.exists()) {
4152                    if (lastTracesFile != null) {
4153                        curTracesFile.renameTo(lastTracesFile);
4154                    } else {
4155                        curTracesFile.delete();
4156                    }
4157                }
4158                lastTracesFile = curTracesFile;
4159            }
4160            tracesFile.renameTo(curTracesFile);
4161            if (tracesTmp.exists()) {
4162                tracesTmp.renameTo(tracesFile);
4163            }
4164        } finally {
4165            StrictMode.setThreadPolicy(oldPolicy);
4166        }
4167    }
4168
4169    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4170            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4171        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4172        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4173
4174        if (mController != null) {
4175            try {
4176                // 0 == continue, -1 = kill process immediately
4177                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4178                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4179            } catch (RemoteException e) {
4180                mController = null;
4181                Watchdog.getInstance().setActivityController(null);
4182            }
4183        }
4184
4185        long anrTime = SystemClock.uptimeMillis();
4186        if (MONITOR_CPU_USAGE) {
4187            updateCpuStatsNow();
4188        }
4189
4190        synchronized (this) {
4191            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4192            if (mShuttingDown) {
4193                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4194                return;
4195            } else if (app.notResponding) {
4196                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4197                return;
4198            } else if (app.crashing) {
4199                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4200                return;
4201            }
4202
4203            // In case we come through here for the same app before completing
4204            // this one, mark as anring now so we will bail out.
4205            app.notResponding = true;
4206
4207            // Log the ANR to the event log.
4208            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4209                    app.processName, app.info.flags, annotation);
4210
4211            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4212            firstPids.add(app.pid);
4213
4214            int parentPid = app.pid;
4215            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4216            if (parentPid != app.pid) firstPids.add(parentPid);
4217
4218            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4219
4220            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4221                ProcessRecord r = mLruProcesses.get(i);
4222                if (r != null && r.thread != null) {
4223                    int pid = r.pid;
4224                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4225                        if (r.persistent) {
4226                            firstPids.add(pid);
4227                        } else {
4228                            lastPids.put(pid, Boolean.TRUE);
4229                        }
4230                    }
4231                }
4232            }
4233        }
4234
4235        // Log the ANR to the main log.
4236        StringBuilder info = new StringBuilder();
4237        info.setLength(0);
4238        info.append("ANR in ").append(app.processName);
4239        if (activity != null && activity.shortComponentName != null) {
4240            info.append(" (").append(activity.shortComponentName).append(")");
4241        }
4242        info.append("\n");
4243        info.append("PID: ").append(app.pid).append("\n");
4244        if (annotation != null) {
4245            info.append("Reason: ").append(annotation).append("\n");
4246        }
4247        if (parent != null && parent != activity) {
4248            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4249        }
4250
4251        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4252
4253        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4254                NATIVE_STACKS_OF_INTEREST);
4255
4256        String cpuInfo = null;
4257        if (MONITOR_CPU_USAGE) {
4258            updateCpuStatsNow();
4259            synchronized (mProcessCpuThread) {
4260                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4261            }
4262            info.append(processCpuTracker.printCurrentLoad());
4263            info.append(cpuInfo);
4264        }
4265
4266        info.append(processCpuTracker.printCurrentState(anrTime));
4267
4268        Slog.e(TAG, info.toString());
4269        if (tracesFile == null) {
4270            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4271            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4272        }
4273
4274        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4275                cpuInfo, tracesFile, null);
4276
4277        if (mController != null) {
4278            try {
4279                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4280                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4281                if (res != 0) {
4282                    if (res < 0 && app.pid != MY_PID) {
4283                        Process.killProcess(app.pid);
4284                    } else {
4285                        synchronized (this) {
4286                            mServices.scheduleServiceTimeoutLocked(app);
4287                        }
4288                    }
4289                    return;
4290                }
4291            } catch (RemoteException e) {
4292                mController = null;
4293                Watchdog.getInstance().setActivityController(null);
4294            }
4295        }
4296
4297        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4298        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4299                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4300
4301        synchronized (this) {
4302            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4303                killUnneededProcessLocked(app, "background ANR");
4304                return;
4305            }
4306
4307            // Set the app's notResponding state, and look up the errorReportReceiver
4308            makeAppNotRespondingLocked(app,
4309                    activity != null ? activity.shortComponentName : null,
4310                    annotation != null ? "ANR " + annotation : "ANR",
4311                    info.toString());
4312
4313            // Bring up the infamous App Not Responding dialog
4314            Message msg = Message.obtain();
4315            HashMap<String, Object> map = new HashMap<String, Object>();
4316            msg.what = SHOW_NOT_RESPONDING_MSG;
4317            msg.obj = map;
4318            msg.arg1 = aboveSystem ? 1 : 0;
4319            map.put("app", app);
4320            if (activity != null) {
4321                map.put("activity", activity);
4322            }
4323
4324            mHandler.sendMessage(msg);
4325        }
4326    }
4327
4328    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4329        if (!mLaunchWarningShown) {
4330            mLaunchWarningShown = true;
4331            mHandler.post(new Runnable() {
4332                @Override
4333                public void run() {
4334                    synchronized (ActivityManagerService.this) {
4335                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4336                        d.show();
4337                        mHandler.postDelayed(new Runnable() {
4338                            @Override
4339                            public void run() {
4340                                synchronized (ActivityManagerService.this) {
4341                                    d.dismiss();
4342                                    mLaunchWarningShown = false;
4343                                }
4344                            }
4345                        }, 4000);
4346                    }
4347                }
4348            });
4349        }
4350    }
4351
4352    @Override
4353    public boolean clearApplicationUserData(final String packageName,
4354            final IPackageDataObserver observer, int userId) {
4355        enforceNotIsolatedCaller("clearApplicationUserData");
4356        int uid = Binder.getCallingUid();
4357        int pid = Binder.getCallingPid();
4358        userId = handleIncomingUser(pid, uid,
4359                userId, false, true, "clearApplicationUserData", null);
4360        long callingId = Binder.clearCallingIdentity();
4361        try {
4362            IPackageManager pm = AppGlobals.getPackageManager();
4363            int pkgUid = -1;
4364            synchronized(this) {
4365                try {
4366                    pkgUid = pm.getPackageUid(packageName, userId);
4367                } catch (RemoteException e) {
4368                }
4369                if (pkgUid == -1) {
4370                    Slog.w(TAG, "Invalid packageName: " + packageName);
4371                    if (observer != null) {
4372                        try {
4373                            observer.onRemoveCompleted(packageName, false);
4374                        } catch (RemoteException e) {
4375                            Slog.i(TAG, "Observer no longer exists.");
4376                        }
4377                    }
4378                    return false;
4379                }
4380                if (uid == pkgUid || checkComponentPermission(
4381                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4382                        pid, uid, -1, true)
4383                        == PackageManager.PERMISSION_GRANTED) {
4384                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4385                } else {
4386                    throw new SecurityException("PID " + pid + " does not have permission "
4387                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4388                                    + " of package " + packageName);
4389                }
4390            }
4391
4392            try {
4393                // Clear application user data
4394                pm.clearApplicationUserData(packageName, observer, userId);
4395
4396                // Remove all permissions granted from/to this package
4397                removeUriPermissionsForPackageLocked(packageName, userId, true);
4398
4399                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4400                        Uri.fromParts("package", packageName, null));
4401                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4402                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4403                        null, null, 0, null, null, null, false, false, userId);
4404            } catch (RemoteException e) {
4405            }
4406        } finally {
4407            Binder.restoreCallingIdentity(callingId);
4408        }
4409        return true;
4410    }
4411
4412    @Override
4413    public void killBackgroundProcesses(final String packageName, int userId) {
4414        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4415                != PackageManager.PERMISSION_GRANTED &&
4416                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4417                        != PackageManager.PERMISSION_GRANTED) {
4418            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4419                    + Binder.getCallingPid()
4420                    + ", uid=" + Binder.getCallingUid()
4421                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4422            Slog.w(TAG, msg);
4423            throw new SecurityException(msg);
4424        }
4425
4426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4427                userId, true, true, "killBackgroundProcesses", null);
4428        long callingId = Binder.clearCallingIdentity();
4429        try {
4430            IPackageManager pm = AppGlobals.getPackageManager();
4431            synchronized(this) {
4432                int appId = -1;
4433                try {
4434                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4435                } catch (RemoteException e) {
4436                }
4437                if (appId == -1) {
4438                    Slog.w(TAG, "Invalid packageName: " + packageName);
4439                    return;
4440                }
4441                killPackageProcessesLocked(packageName, appId, userId,
4442                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4443            }
4444        } finally {
4445            Binder.restoreCallingIdentity(callingId);
4446        }
4447    }
4448
4449    @Override
4450    public void killAllBackgroundProcesses() {
4451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4452                != PackageManager.PERMISSION_GRANTED) {
4453            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4454                    + Binder.getCallingPid()
4455                    + ", uid=" + Binder.getCallingUid()
4456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4457            Slog.w(TAG, msg);
4458            throw new SecurityException(msg);
4459        }
4460
4461        long callingId = Binder.clearCallingIdentity();
4462        try {
4463            synchronized(this) {
4464                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4465                final int NP = mProcessNames.getMap().size();
4466                for (int ip=0; ip<NP; ip++) {
4467                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4468                    final int NA = apps.size();
4469                    for (int ia=0; ia<NA; ia++) {
4470                        ProcessRecord app = apps.valueAt(ia);
4471                        if (app.persistent) {
4472                            // we don't kill persistent processes
4473                            continue;
4474                        }
4475                        if (app.removed) {
4476                            procs.add(app);
4477                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4478                            app.removed = true;
4479                            procs.add(app);
4480                        }
4481                    }
4482                }
4483
4484                int N = procs.size();
4485                for (int i=0; i<N; i++) {
4486                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4487                }
4488                mAllowLowerMemLevel = true;
4489                updateOomAdjLocked();
4490                doLowMemReportIfNeededLocked(null);
4491            }
4492        } finally {
4493            Binder.restoreCallingIdentity(callingId);
4494        }
4495    }
4496
4497    @Override
4498    public void forceStopPackage(final String packageName, int userId) {
4499        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4500                != PackageManager.PERMISSION_GRANTED) {
4501            String msg = "Permission Denial: forceStopPackage() from pid="
4502                    + Binder.getCallingPid()
4503                    + ", uid=" + Binder.getCallingUid()
4504                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4505            Slog.w(TAG, msg);
4506            throw new SecurityException(msg);
4507        }
4508        final int callingPid = Binder.getCallingPid();
4509        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4510                userId, true, true, "forceStopPackage", null);
4511        long callingId = Binder.clearCallingIdentity();
4512        try {
4513            IPackageManager pm = AppGlobals.getPackageManager();
4514            synchronized(this) {
4515                int[] users = userId == UserHandle.USER_ALL
4516                        ? getUsersLocked() : new int[] { userId };
4517                for (int user : users) {
4518                    int pkgUid = -1;
4519                    try {
4520                        pkgUid = pm.getPackageUid(packageName, user);
4521                    } catch (RemoteException e) {
4522                    }
4523                    if (pkgUid == -1) {
4524                        Slog.w(TAG, "Invalid packageName: " + packageName);
4525                        continue;
4526                    }
4527                    try {
4528                        pm.setPackageStoppedState(packageName, true, user);
4529                    } catch (RemoteException e) {
4530                    } catch (IllegalArgumentException e) {
4531                        Slog.w(TAG, "Failed trying to unstop package "
4532                                + packageName + ": " + e);
4533                    }
4534                    if (isUserRunningLocked(user, false)) {
4535                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4536                    }
4537                }
4538            }
4539        } finally {
4540            Binder.restoreCallingIdentity(callingId);
4541        }
4542    }
4543
4544    /*
4545     * The pkg name and app id have to be specified.
4546     */
4547    @Override
4548    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4549        if (pkg == null) {
4550            return;
4551        }
4552        // Make sure the uid is valid.
4553        if (appid < 0) {
4554            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4555            return;
4556        }
4557        int callerUid = Binder.getCallingUid();
4558        // Only the system server can kill an application
4559        if (callerUid == Process.SYSTEM_UID) {
4560            // Post an aysnc message to kill the application
4561            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4562            msg.arg1 = appid;
4563            msg.arg2 = 0;
4564            Bundle bundle = new Bundle();
4565            bundle.putString("pkg", pkg);
4566            bundle.putString("reason", reason);
4567            msg.obj = bundle;
4568            mHandler.sendMessage(msg);
4569        } else {
4570            throw new SecurityException(callerUid + " cannot kill pkg: " +
4571                    pkg);
4572        }
4573    }
4574
4575    @Override
4576    public void closeSystemDialogs(String reason) {
4577        enforceNotIsolatedCaller("closeSystemDialogs");
4578
4579        final int pid = Binder.getCallingPid();
4580        final int uid = Binder.getCallingUid();
4581        final long origId = Binder.clearCallingIdentity();
4582        try {
4583            synchronized (this) {
4584                // Only allow this from foreground processes, so that background
4585                // applications can't abuse it to prevent system UI from being shown.
4586                if (uid >= Process.FIRST_APPLICATION_UID) {
4587                    ProcessRecord proc;
4588                    synchronized (mPidsSelfLocked) {
4589                        proc = mPidsSelfLocked.get(pid);
4590                    }
4591                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4592                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4593                                + " from background process " + proc);
4594                        return;
4595                    }
4596                }
4597                closeSystemDialogsLocked(reason);
4598            }
4599        } finally {
4600            Binder.restoreCallingIdentity(origId);
4601        }
4602    }
4603
4604    void closeSystemDialogsLocked(String reason) {
4605        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4606        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4607                | Intent.FLAG_RECEIVER_FOREGROUND);
4608        if (reason != null) {
4609            intent.putExtra("reason", reason);
4610        }
4611        mWindowManager.closeSystemDialogs(reason);
4612
4613        mStackSupervisor.closeSystemDialogsLocked();
4614
4615        broadcastIntentLocked(null, null, intent, null,
4616                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4617                Process.SYSTEM_UID, UserHandle.USER_ALL);
4618    }
4619
4620    @Override
4621    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4622        enforceNotIsolatedCaller("getProcessMemoryInfo");
4623        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4624        for (int i=pids.length-1; i>=0; i--) {
4625            ProcessRecord proc;
4626            int oomAdj;
4627            synchronized (this) {
4628                synchronized (mPidsSelfLocked) {
4629                    proc = mPidsSelfLocked.get(pids[i]);
4630                    oomAdj = proc != null ? proc.setAdj : 0;
4631                }
4632            }
4633            infos[i] = new Debug.MemoryInfo();
4634            Debug.getMemoryInfo(pids[i], infos[i]);
4635            if (proc != null) {
4636                synchronized (this) {
4637                    if (proc.thread != null && proc.setAdj == oomAdj) {
4638                        // Record this for posterity if the process has been stable.
4639                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4640                                infos[i].getTotalUss(), false, proc.pkgList);
4641                    }
4642                }
4643            }
4644        }
4645        return infos;
4646    }
4647
4648    @Override
4649    public long[] getProcessPss(int[] pids) {
4650        enforceNotIsolatedCaller("getProcessPss");
4651        long[] pss = new long[pids.length];
4652        for (int i=pids.length-1; i>=0; i--) {
4653            ProcessRecord proc;
4654            int oomAdj;
4655            synchronized (this) {
4656                synchronized (mPidsSelfLocked) {
4657                    proc = mPidsSelfLocked.get(pids[i]);
4658                    oomAdj = proc != null ? proc.setAdj : 0;
4659                }
4660            }
4661            long[] tmpUss = new long[1];
4662            pss[i] = Debug.getPss(pids[i], tmpUss);
4663            if (proc != null) {
4664                synchronized (this) {
4665                    if (proc.thread != null && proc.setAdj == oomAdj) {
4666                        // Record this for posterity if the process has been stable.
4667                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4668                    }
4669                }
4670            }
4671        }
4672        return pss;
4673    }
4674
4675    @Override
4676    public void killApplicationProcess(String processName, int uid) {
4677        if (processName == null) {
4678            return;
4679        }
4680
4681        int callerUid = Binder.getCallingUid();
4682        // Only the system server can kill an application
4683        if (callerUid == Process.SYSTEM_UID) {
4684            synchronized (this) {
4685                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4686                if (app != null && app.thread != null) {
4687                    try {
4688                        app.thread.scheduleSuicide();
4689                    } catch (RemoteException e) {
4690                        // If the other end already died, then our work here is done.
4691                    }
4692                } else {
4693                    Slog.w(TAG, "Process/uid not found attempting kill of "
4694                            + processName + " / " + uid);
4695                }
4696            }
4697        } else {
4698            throw new SecurityException(callerUid + " cannot kill app process: " +
4699                    processName);
4700        }
4701    }
4702
4703    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4704        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4705                false, true, false, false, UserHandle.getUserId(uid), reason);
4706        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4707                Uri.fromParts("package", packageName, null));
4708        if (!mProcessesReady) {
4709            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4710                    | Intent.FLAG_RECEIVER_FOREGROUND);
4711        }
4712        intent.putExtra(Intent.EXTRA_UID, uid);
4713        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4714        broadcastIntentLocked(null, null, intent,
4715                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4716                false, false,
4717                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4718    }
4719
4720    private void forceStopUserLocked(int userId, String reason) {
4721        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4722        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4723        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4724                | Intent.FLAG_RECEIVER_FOREGROUND);
4725        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4726        broadcastIntentLocked(null, null, intent,
4727                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4728                false, false,
4729                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4730    }
4731
4732    private final boolean killPackageProcessesLocked(String packageName, int appId,
4733            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4734            boolean doit, boolean evenPersistent, String reason) {
4735        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4736
4737        // Remove all processes this package may have touched: all with the
4738        // same UID (except for the system or root user), and all whose name
4739        // matches the package name.
4740        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4741        final int NP = mProcessNames.getMap().size();
4742        for (int ip=0; ip<NP; ip++) {
4743            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4744            final int NA = apps.size();
4745            for (int ia=0; ia<NA; ia++) {
4746                ProcessRecord app = apps.valueAt(ia);
4747                if (app.persistent && !evenPersistent) {
4748                    // we don't kill persistent processes
4749                    continue;
4750                }
4751                if (app.removed) {
4752                    if (doit) {
4753                        procs.add(app);
4754                    }
4755                    continue;
4756                }
4757
4758                // Skip process if it doesn't meet our oom adj requirement.
4759                if (app.setAdj < minOomAdj) {
4760                    continue;
4761                }
4762
4763                // If no package is specified, we call all processes under the
4764                // give user id.
4765                if (packageName == null) {
4766                    if (app.userId != userId) {
4767                        continue;
4768                    }
4769                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4770                        continue;
4771                    }
4772                // Package has been specified, we want to hit all processes
4773                // that match it.  We need to qualify this by the processes
4774                // that are running under the specified app and user ID.
4775                } else {
4776                    if (UserHandle.getAppId(app.uid) != appId) {
4777                        continue;
4778                    }
4779                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4780                        continue;
4781                    }
4782                    if (!app.pkgList.containsKey(packageName)) {
4783                        continue;
4784                    }
4785                }
4786
4787                // Process has passed all conditions, kill it!
4788                if (!doit) {
4789                    return true;
4790                }
4791                app.removed = true;
4792                procs.add(app);
4793            }
4794        }
4795
4796        int N = procs.size();
4797        for (int i=0; i<N; i++) {
4798            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4799        }
4800        updateOomAdjLocked();
4801        return N > 0;
4802    }
4803
4804    private final boolean forceStopPackageLocked(String name, int appId,
4805            boolean callerWillRestart, boolean purgeCache, boolean doit,
4806            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4807        int i;
4808        int N;
4809
4810        if (userId == UserHandle.USER_ALL && name == null) {
4811            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4812        }
4813
4814        if (appId < 0 && name != null) {
4815            try {
4816                appId = UserHandle.getAppId(
4817                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4818            } catch (RemoteException e) {
4819            }
4820        }
4821
4822        if (doit) {
4823            if (name != null) {
4824                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4825                        + " user=" + userId + ": " + reason);
4826            } else {
4827                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4828            }
4829
4830            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4831            for (int ip=pmap.size()-1; ip>=0; ip--) {
4832                SparseArray<Long> ba = pmap.valueAt(ip);
4833                for (i=ba.size()-1; i>=0; i--) {
4834                    boolean remove = false;
4835                    final int entUid = ba.keyAt(i);
4836                    if (name != null) {
4837                        if (userId == UserHandle.USER_ALL) {
4838                            if (UserHandle.getAppId(entUid) == appId) {
4839                                remove = true;
4840                            }
4841                        } else {
4842                            if (entUid == UserHandle.getUid(userId, appId)) {
4843                                remove = true;
4844                            }
4845                        }
4846                    } else if (UserHandle.getUserId(entUid) == userId) {
4847                        remove = true;
4848                    }
4849                    if (remove) {
4850                        ba.removeAt(i);
4851                    }
4852                }
4853                if (ba.size() == 0) {
4854                    pmap.removeAt(ip);
4855                }
4856            }
4857        }
4858
4859        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4860                -100, callerWillRestart, true, doit, evenPersistent,
4861                name == null ? ("stop user " + userId) : ("stop " + name));
4862
4863        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4864            if (!doit) {
4865                return true;
4866            }
4867            didSomething = true;
4868        }
4869
4870        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4871            if (!doit) {
4872                return true;
4873            }
4874            didSomething = true;
4875        }
4876
4877        if (name == null) {
4878            // Remove all sticky broadcasts from this user.
4879            mStickyBroadcasts.remove(userId);
4880        }
4881
4882        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4883        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4884                userId, providers)) {
4885            if (!doit) {
4886                return true;
4887            }
4888            didSomething = true;
4889        }
4890        N = providers.size();
4891        for (i=0; i<N; i++) {
4892            removeDyingProviderLocked(null, providers.get(i), true);
4893        }
4894
4895        // Remove transient permissions granted from/to this package/user
4896        removeUriPermissionsForPackageLocked(name, userId, false);
4897
4898        if (name == null || uninstalling) {
4899            // Remove pending intents.  For now we only do this when force
4900            // stopping users, because we have some problems when doing this
4901            // for packages -- app widgets are not currently cleaned up for
4902            // such packages, so they can be left with bad pending intents.
4903            if (mIntentSenderRecords.size() > 0) {
4904                Iterator<WeakReference<PendingIntentRecord>> it
4905                        = mIntentSenderRecords.values().iterator();
4906                while (it.hasNext()) {
4907                    WeakReference<PendingIntentRecord> wpir = it.next();
4908                    if (wpir == null) {
4909                        it.remove();
4910                        continue;
4911                    }
4912                    PendingIntentRecord pir = wpir.get();
4913                    if (pir == null) {
4914                        it.remove();
4915                        continue;
4916                    }
4917                    if (name == null) {
4918                        // Stopping user, remove all objects for the user.
4919                        if (pir.key.userId != userId) {
4920                            // Not the same user, skip it.
4921                            continue;
4922                        }
4923                    } else {
4924                        if (UserHandle.getAppId(pir.uid) != appId) {
4925                            // Different app id, skip it.
4926                            continue;
4927                        }
4928                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4929                            // Different user, skip it.
4930                            continue;
4931                        }
4932                        if (!pir.key.packageName.equals(name)) {
4933                            // Different package, skip it.
4934                            continue;
4935                        }
4936                    }
4937                    if (!doit) {
4938                        return true;
4939                    }
4940                    didSomething = true;
4941                    it.remove();
4942                    pir.canceled = true;
4943                    if (pir.key.activity != null) {
4944                        pir.key.activity.pendingResults.remove(pir.ref);
4945                    }
4946                }
4947            }
4948        }
4949
4950        if (doit) {
4951            if (purgeCache && name != null) {
4952                AttributeCache ac = AttributeCache.instance();
4953                if (ac != null) {
4954                    ac.removePackage(name);
4955                }
4956            }
4957            if (mBooted) {
4958                mStackSupervisor.resumeTopActivitiesLocked();
4959                mStackSupervisor.scheduleIdleLocked();
4960            }
4961        }
4962
4963        return didSomething;
4964    }
4965
4966    private final boolean removeProcessLocked(ProcessRecord app,
4967            boolean callerWillRestart, boolean allowRestart, String reason) {
4968        final String name = app.processName;
4969        final int uid = app.uid;
4970        if (DEBUG_PROCESSES) Slog.d(
4971            TAG, "Force removing proc " + app.toShortString() + " (" + name
4972            + "/" + uid + ")");
4973
4974        mProcessNames.remove(name, uid);
4975        mIsolatedProcesses.remove(app.uid);
4976        if (mHeavyWeightProcess == app) {
4977            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4978                    mHeavyWeightProcess.userId, 0));
4979            mHeavyWeightProcess = null;
4980        }
4981        boolean needRestart = false;
4982        if (app.pid > 0 && app.pid != MY_PID) {
4983            int pid = app.pid;
4984            synchronized (mPidsSelfLocked) {
4985                mPidsSelfLocked.remove(pid);
4986                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4987            }
4988            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4989                    app.processName, app.info.uid);
4990            if (app.isolated) {
4991                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4992            }
4993            killUnneededProcessLocked(app, reason);
4994            handleAppDiedLocked(app, true, allowRestart);
4995            removeLruProcessLocked(app);
4996
4997            if (app.persistent && !app.isolated) {
4998                if (!callerWillRestart) {
4999                    addAppLocked(app.info, false);
5000                } else {
5001                    needRestart = true;
5002                }
5003            }
5004        } else {
5005            mRemovedProcesses.add(app);
5006        }
5007
5008        return needRestart;
5009    }
5010
5011    private final void processStartTimedOutLocked(ProcessRecord app) {
5012        final int pid = app.pid;
5013        boolean gone = false;
5014        synchronized (mPidsSelfLocked) {
5015            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5016            if (knownApp != null && knownApp.thread == null) {
5017                mPidsSelfLocked.remove(pid);
5018                gone = true;
5019            }
5020        }
5021
5022        if (gone) {
5023            Slog.w(TAG, "Process " + app + " failed to attach");
5024            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5025                    pid, app.uid, app.processName);
5026            mProcessNames.remove(app.processName, app.uid);
5027            mIsolatedProcesses.remove(app.uid);
5028            if (mHeavyWeightProcess == app) {
5029                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5030                        mHeavyWeightProcess.userId, 0));
5031                mHeavyWeightProcess = null;
5032            }
5033            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5034                    app.processName, app.info.uid);
5035            if (app.isolated) {
5036                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5037            }
5038            // Take care of any launching providers waiting for this process.
5039            checkAppInLaunchingProvidersLocked(app, true);
5040            // Take care of any services that are waiting for the process.
5041            mServices.processStartTimedOutLocked(app);
5042            killUnneededProcessLocked(app, "start timeout");
5043            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5044                Slog.w(TAG, "Unattached app died before backup, skipping");
5045                try {
5046                    IBackupManager bm = IBackupManager.Stub.asInterface(
5047                            ServiceManager.getService(Context.BACKUP_SERVICE));
5048                    bm.agentDisconnected(app.info.packageName);
5049                } catch (RemoteException e) {
5050                    // Can't happen; the backup manager is local
5051                }
5052            }
5053            if (isPendingBroadcastProcessLocked(pid)) {
5054                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5055                skipPendingBroadcastLocked(pid);
5056            }
5057        } else {
5058            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5059        }
5060    }
5061
5062    private final boolean attachApplicationLocked(IApplicationThread thread,
5063            int pid) {
5064
5065        // Find the application record that is being attached...  either via
5066        // the pid if we are running in multiple processes, or just pull the
5067        // next app record if we are emulating process with anonymous threads.
5068        ProcessRecord app;
5069        if (pid != MY_PID && pid >= 0) {
5070            synchronized (mPidsSelfLocked) {
5071                app = mPidsSelfLocked.get(pid);
5072            }
5073        } else {
5074            app = null;
5075        }
5076
5077        if (app == null) {
5078            Slog.w(TAG, "No pending application record for pid " + pid
5079                    + " (IApplicationThread " + thread + "); dropping process");
5080            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5081            if (pid > 0 && pid != MY_PID) {
5082                Process.killProcessQuiet(pid);
5083            } else {
5084                try {
5085                    thread.scheduleExit();
5086                } catch (Exception e) {
5087                    // Ignore exceptions.
5088                }
5089            }
5090            return false;
5091        }
5092
5093        // If this application record is still attached to a previous
5094        // process, clean it up now.
5095        if (app.thread != null) {
5096            handleAppDiedLocked(app, true, true);
5097        }
5098
5099        // Tell the process all about itself.
5100
5101        if (localLOGV) Slog.v(
5102                TAG, "Binding process pid " + pid + " to record " + app);
5103
5104        final String processName = app.processName;
5105        try {
5106            AppDeathRecipient adr = new AppDeathRecipient(
5107                    app, pid, thread);
5108            thread.asBinder().linkToDeath(adr, 0);
5109            app.deathRecipient = adr;
5110        } catch (RemoteException e) {
5111            app.resetPackageList(mProcessStats);
5112            startProcessLocked(app, "link fail", processName);
5113            return false;
5114        }
5115
5116        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5117
5118        app.makeActive(thread, mProcessStats);
5119        app.curAdj = app.setAdj = -100;
5120        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5121        app.forcingToForeground = null;
5122        updateProcessForegroundLocked(app, false, false);
5123        app.hasShownUi = false;
5124        app.debugging = false;
5125        app.cached = false;
5126
5127        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5128
5129        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5130        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5131
5132        if (!normalMode) {
5133            Slog.i(TAG, "Launching preboot mode app: " + app);
5134        }
5135
5136        if (localLOGV) Slog.v(
5137            TAG, "New app record " + app
5138            + " thread=" + thread.asBinder() + " pid=" + pid);
5139        try {
5140            int testMode = IApplicationThread.DEBUG_OFF;
5141            if (mDebugApp != null && mDebugApp.equals(processName)) {
5142                testMode = mWaitForDebugger
5143                    ? IApplicationThread.DEBUG_WAIT
5144                    : IApplicationThread.DEBUG_ON;
5145                app.debugging = true;
5146                if (mDebugTransient) {
5147                    mDebugApp = mOrigDebugApp;
5148                    mWaitForDebugger = mOrigWaitForDebugger;
5149                }
5150            }
5151            String profileFile = app.instrumentationProfileFile;
5152            ParcelFileDescriptor profileFd = null;
5153            boolean profileAutoStop = false;
5154            if (mProfileApp != null && mProfileApp.equals(processName)) {
5155                mProfileProc = app;
5156                profileFile = mProfileFile;
5157                profileFd = mProfileFd;
5158                profileAutoStop = mAutoStopProfiler;
5159            }
5160            boolean enableOpenGlTrace = false;
5161            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5162                enableOpenGlTrace = true;
5163                mOpenGlTraceApp = null;
5164            }
5165
5166            // If the app is being launched for restore or full backup, set it up specially
5167            boolean isRestrictedBackupMode = false;
5168            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5169                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5170                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5171                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5172            }
5173
5174            ensurePackageDexOpt(app.instrumentationInfo != null
5175                    ? app.instrumentationInfo.packageName
5176                    : app.info.packageName);
5177            if (app.instrumentationClass != null) {
5178                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5179            }
5180            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5181                    + processName + " with config " + mConfiguration);
5182            ApplicationInfo appInfo = app.instrumentationInfo != null
5183                    ? app.instrumentationInfo : app.info;
5184            app.compat = compatibilityInfoForPackageLocked(appInfo);
5185            if (profileFd != null) {
5186                profileFd = profileFd.dup();
5187            }
5188            thread.bindApplication(processName, appInfo, providers,
5189                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5190                    app.instrumentationArguments, app.instrumentationWatcher,
5191                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5192                    isRestrictedBackupMode || !normalMode, app.persistent,
5193                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5194                    mCoreSettingsObserver.getCoreSettingsLocked());
5195            updateLruProcessLocked(app, false, null);
5196            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5197        } catch (Exception e) {
5198            // todo: Yikes!  What should we do?  For now we will try to
5199            // start another process, but that could easily get us in
5200            // an infinite loop of restarting processes...
5201            Slog.w(TAG, "Exception thrown during bind!", e);
5202
5203            app.resetPackageList(mProcessStats);
5204            app.unlinkDeathRecipient();
5205            startProcessLocked(app, "bind fail", processName);
5206            return false;
5207        }
5208
5209        // Remove this record from the list of starting applications.
5210        mPersistentStartingProcesses.remove(app);
5211        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5212                "Attach application locked removing on hold: " + app);
5213        mProcessesOnHold.remove(app);
5214
5215        boolean badApp = false;
5216        boolean didSomething = false;
5217
5218        // See if the top visible activity is waiting to run in this process...
5219        if (normalMode) {
5220            try {
5221                if (mStackSupervisor.attachApplicationLocked(app)) {
5222                    didSomething = true;
5223                }
5224            } catch (Exception e) {
5225                badApp = true;
5226            }
5227        }
5228
5229        // Find any services that should be running in this process...
5230        if (!badApp) {
5231            try {
5232                didSomething |= mServices.attachApplicationLocked(app, processName);
5233            } catch (Exception e) {
5234                badApp = true;
5235            }
5236        }
5237
5238        // Check if a next-broadcast receiver is in this process...
5239        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5240            try {
5241                didSomething |= sendPendingBroadcastsLocked(app);
5242            } catch (Exception e) {
5243                // If the app died trying to launch the receiver we declare it 'bad'
5244                badApp = true;
5245            }
5246        }
5247
5248        // Check whether the next backup agent is in this process...
5249        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5250            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5251            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5252            try {
5253                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5254                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5255                        mBackupTarget.backupMode);
5256            } catch (Exception e) {
5257                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5258                e.printStackTrace();
5259            }
5260        }
5261
5262        if (badApp) {
5263            // todo: Also need to kill application to deal with all
5264            // kinds of exceptions.
5265            handleAppDiedLocked(app, false, true);
5266            return false;
5267        }
5268
5269        if (!didSomething) {
5270            updateOomAdjLocked();
5271        }
5272
5273        return true;
5274    }
5275
5276    @Override
5277    public final void attachApplication(IApplicationThread thread) {
5278        synchronized (this) {
5279            int callingPid = Binder.getCallingPid();
5280            final long origId = Binder.clearCallingIdentity();
5281            attachApplicationLocked(thread, callingPid);
5282            Binder.restoreCallingIdentity(origId);
5283        }
5284    }
5285
5286    @Override
5287    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5288        final long origId = Binder.clearCallingIdentity();
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                ActivityRecord r =
5293                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5294                if (stopProfiling) {
5295                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5296                        try {
5297                            mProfileFd.close();
5298                        } catch (IOException e) {
5299                        }
5300                        clearProfilerLocked();
5301                    }
5302                }
5303            }
5304        }
5305        Binder.restoreCallingIdentity(origId);
5306    }
5307
5308    void enableScreenAfterBoot() {
5309        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5310                SystemClock.uptimeMillis());
5311        mWindowManager.enableScreenAfterBoot();
5312
5313        synchronized (this) {
5314            updateEventDispatchingLocked();
5315        }
5316    }
5317
5318    @Override
5319    public void showBootMessage(final CharSequence msg, final boolean always) {
5320        enforceNotIsolatedCaller("showBootMessage");
5321        mWindowManager.showBootMessage(msg, always);
5322    }
5323
5324    @Override
5325    public void dismissKeyguardOnNextActivity() {
5326        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5327        final long token = Binder.clearCallingIdentity();
5328        try {
5329            synchronized (this) {
5330                if (DEBUG_LOCKSCREEN) logLockScreen("");
5331                if (mLockScreenShown) {
5332                    mLockScreenShown = false;
5333                    comeOutOfSleepIfNeededLocked();
5334                }
5335                mStackSupervisor.setDismissKeyguard(true);
5336            }
5337        } finally {
5338            Binder.restoreCallingIdentity(token);
5339        }
5340    }
5341
5342    final void finishBooting() {
5343        // Register receivers to handle package update events
5344        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5345
5346        synchronized (this) {
5347            // Ensure that any processes we had put on hold are now started
5348            // up.
5349            final int NP = mProcessesOnHold.size();
5350            if (NP > 0) {
5351                ArrayList<ProcessRecord> procs =
5352                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5353                for (int ip=0; ip<NP; ip++) {
5354                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5355                            + procs.get(ip));
5356                    startProcessLocked(procs.get(ip), "on-hold", null);
5357                }
5358            }
5359
5360            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5361                // Start looking for apps that are abusing wake locks.
5362                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5363                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5364                // Tell anyone interested that we are done booting!
5365                SystemProperties.set("sys.boot_completed", "1");
5366                SystemProperties.set("dev.bootcomplete", "1");
5367                for (int i=0; i<mStartedUsers.size(); i++) {
5368                    UserStartedState uss = mStartedUsers.valueAt(i);
5369                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5370                        uss.mState = UserStartedState.STATE_RUNNING;
5371                        final int userId = mStartedUsers.keyAt(i);
5372                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5373                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5374                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5375                        broadcastIntentLocked(null, null, intent, null,
5376                                new IIntentReceiver.Stub() {
5377                                    @Override
5378                                    public void performReceive(Intent intent, int resultCode,
5379                                            String data, Bundle extras, boolean ordered,
5380                                            boolean sticky, int sendingUser) {
5381                                        synchronized (ActivityManagerService.this) {
5382                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5383                                                    true, false);
5384                                        }
5385                                    }
5386                                },
5387                                0, null, null,
5388                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5389                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5390                                userId);
5391                    }
5392                }
5393                scheduleStartProfilesLocked();
5394            }
5395        }
5396    }
5397
5398    final void ensureBootCompleted() {
5399        boolean booting;
5400        boolean enableScreen;
5401        synchronized (this) {
5402            booting = mBooting;
5403            mBooting = false;
5404            enableScreen = !mBooted;
5405            mBooted = true;
5406        }
5407
5408        if (booting) {
5409            finishBooting();
5410        }
5411
5412        if (enableScreen) {
5413            enableScreenAfterBoot();
5414        }
5415    }
5416
5417    @Override
5418    public final void activityResumed(IBinder token) {
5419        final long origId = Binder.clearCallingIdentity();
5420        synchronized(this) {
5421            ActivityStack stack = ActivityRecord.getStackLocked(token);
5422            if (stack != null) {
5423                ActivityRecord.activityResumedLocked(token);
5424            }
5425        }
5426        Binder.restoreCallingIdentity(origId);
5427    }
5428
5429    @Override
5430    public final void activityPaused(IBinder token) {
5431        final long origId = Binder.clearCallingIdentity();
5432        synchronized(this) {
5433            ActivityStack stack = ActivityRecord.getStackLocked(token);
5434            if (stack != null) {
5435                stack.activityPausedLocked(token, false);
5436            }
5437        }
5438        Binder.restoreCallingIdentity(origId);
5439    }
5440
5441    @Override
5442    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5443            CharSequence description) {
5444        if (localLOGV) Slog.v(
5445            TAG, "Activity stopped: token=" + token);
5446
5447        // Refuse possible leaked file descriptors
5448        if (icicle != null && icicle.hasFileDescriptors()) {
5449            throw new IllegalArgumentException("File descriptors passed in Bundle");
5450        }
5451
5452        final long origId = Binder.clearCallingIdentity();
5453
5454        synchronized (this) {
5455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5456            if (r != null) {
5457                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5458            }
5459        }
5460
5461        trimApplications();
5462
5463        Binder.restoreCallingIdentity(origId);
5464    }
5465
5466    @Override
5467    public final void activityDestroyed(IBinder token) {
5468        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5469        synchronized (this) {
5470            ActivityStack stack = ActivityRecord.getStackLocked(token);
5471            if (stack != null) {
5472                stack.activityDestroyedLocked(token);
5473            }
5474        }
5475    }
5476
5477    @Override
5478    public String getCallingPackage(IBinder token) {
5479        synchronized (this) {
5480            ActivityRecord r = getCallingRecordLocked(token);
5481            return r != null ? r.info.packageName : null;
5482        }
5483    }
5484
5485    @Override
5486    public ComponentName getCallingActivity(IBinder token) {
5487        synchronized (this) {
5488            ActivityRecord r = getCallingRecordLocked(token);
5489            return r != null ? r.intent.getComponent() : null;
5490        }
5491    }
5492
5493    private ActivityRecord getCallingRecordLocked(IBinder token) {
5494        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5495        if (r == null) {
5496            return null;
5497        }
5498        return r.resultTo;
5499    }
5500
5501    @Override
5502    public ComponentName getActivityClassForToken(IBinder token) {
5503        synchronized(this) {
5504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5505            if (r == null) {
5506                return null;
5507            }
5508            return r.intent.getComponent();
5509        }
5510    }
5511
5512    @Override
5513    public String getPackageForToken(IBinder token) {
5514        synchronized(this) {
5515            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5516            if (r == null) {
5517                return null;
5518            }
5519            return r.packageName;
5520        }
5521    }
5522
5523    @Override
5524    public IIntentSender getIntentSender(int type,
5525            String packageName, IBinder token, String resultWho,
5526            int requestCode, Intent[] intents, String[] resolvedTypes,
5527            int flags, Bundle options, int userId) {
5528        enforceNotIsolatedCaller("getIntentSender");
5529        // Refuse possible leaked file descriptors
5530        if (intents != null) {
5531            if (intents.length < 1) {
5532                throw new IllegalArgumentException("Intents array length must be >= 1");
5533            }
5534            for (int i=0; i<intents.length; i++) {
5535                Intent intent = intents[i];
5536                if (intent != null) {
5537                    if (intent.hasFileDescriptors()) {
5538                        throw new IllegalArgumentException("File descriptors passed in Intent");
5539                    }
5540                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5541                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5542                        throw new IllegalArgumentException(
5543                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5544                    }
5545                    intents[i] = new Intent(intent);
5546                }
5547            }
5548            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5549                throw new IllegalArgumentException(
5550                        "Intent array length does not match resolvedTypes length");
5551            }
5552        }
5553        if (options != null) {
5554            if (options.hasFileDescriptors()) {
5555                throw new IllegalArgumentException("File descriptors passed in options");
5556            }
5557        }
5558
5559        synchronized(this) {
5560            int callingUid = Binder.getCallingUid();
5561            int origUserId = userId;
5562            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5563                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5564                    "getIntentSender", null);
5565            if (origUserId == UserHandle.USER_CURRENT) {
5566                // We don't want to evaluate this until the pending intent is
5567                // actually executed.  However, we do want to always do the
5568                // security checking for it above.
5569                userId = UserHandle.USER_CURRENT;
5570            }
5571            try {
5572                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5573                    int uid = AppGlobals.getPackageManager()
5574                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5575                    if (!UserHandle.isSameApp(callingUid, uid)) {
5576                        String msg = "Permission Denial: getIntentSender() from pid="
5577                            + Binder.getCallingPid()
5578                            + ", uid=" + Binder.getCallingUid()
5579                            + ", (need uid=" + uid + ")"
5580                            + " is not allowed to send as package " + packageName;
5581                        Slog.w(TAG, msg);
5582                        throw new SecurityException(msg);
5583                    }
5584                }
5585
5586                return getIntentSenderLocked(type, packageName, callingUid, userId,
5587                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5588
5589            } catch (RemoteException e) {
5590                throw new SecurityException(e);
5591            }
5592        }
5593    }
5594
5595    IIntentSender getIntentSenderLocked(int type, String packageName,
5596            int callingUid, int userId, IBinder token, String resultWho,
5597            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5598            Bundle options) {
5599        if (DEBUG_MU)
5600            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5601        ActivityRecord activity = null;
5602        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5603            activity = ActivityRecord.isInStackLocked(token);
5604            if (activity == null) {
5605                return null;
5606            }
5607            if (activity.finishing) {
5608                return null;
5609            }
5610        }
5611
5612        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5613        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5614        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5615        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5616                |PendingIntent.FLAG_UPDATE_CURRENT);
5617
5618        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5619                type, packageName, activity, resultWho,
5620                requestCode, intents, resolvedTypes, flags, options, userId);
5621        WeakReference<PendingIntentRecord> ref;
5622        ref = mIntentSenderRecords.get(key);
5623        PendingIntentRecord rec = ref != null ? ref.get() : null;
5624        if (rec != null) {
5625            if (!cancelCurrent) {
5626                if (updateCurrent) {
5627                    if (rec.key.requestIntent != null) {
5628                        rec.key.requestIntent.replaceExtras(intents != null ?
5629                                intents[intents.length - 1] : null);
5630                    }
5631                    if (intents != null) {
5632                        intents[intents.length-1] = rec.key.requestIntent;
5633                        rec.key.allIntents = intents;
5634                        rec.key.allResolvedTypes = resolvedTypes;
5635                    } else {
5636                        rec.key.allIntents = null;
5637                        rec.key.allResolvedTypes = null;
5638                    }
5639                }
5640                return rec;
5641            }
5642            rec.canceled = true;
5643            mIntentSenderRecords.remove(key);
5644        }
5645        if (noCreate) {
5646            return rec;
5647        }
5648        rec = new PendingIntentRecord(this, key, callingUid);
5649        mIntentSenderRecords.put(key, rec.ref);
5650        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5651            if (activity.pendingResults == null) {
5652                activity.pendingResults
5653                        = new HashSet<WeakReference<PendingIntentRecord>>();
5654            }
5655            activity.pendingResults.add(rec.ref);
5656        }
5657        return rec;
5658    }
5659
5660    @Override
5661    public void cancelIntentSender(IIntentSender sender) {
5662        if (!(sender instanceof PendingIntentRecord)) {
5663            return;
5664        }
5665        synchronized(this) {
5666            PendingIntentRecord rec = (PendingIntentRecord)sender;
5667            try {
5668                int uid = AppGlobals.getPackageManager()
5669                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5670                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5671                    String msg = "Permission Denial: cancelIntentSender() from pid="
5672                        + Binder.getCallingPid()
5673                        + ", uid=" + Binder.getCallingUid()
5674                        + " is not allowed to cancel packges "
5675                        + rec.key.packageName;
5676                    Slog.w(TAG, msg);
5677                    throw new SecurityException(msg);
5678                }
5679            } catch (RemoteException e) {
5680                throw new SecurityException(e);
5681            }
5682            cancelIntentSenderLocked(rec, true);
5683        }
5684    }
5685
5686    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5687        rec.canceled = true;
5688        mIntentSenderRecords.remove(rec.key);
5689        if (cleanActivity && rec.key.activity != null) {
5690            rec.key.activity.pendingResults.remove(rec.ref);
5691        }
5692    }
5693
5694    @Override
5695    public String getPackageForIntentSender(IIntentSender pendingResult) {
5696        if (!(pendingResult instanceof PendingIntentRecord)) {
5697            return null;
5698        }
5699        try {
5700            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5701            return res.key.packageName;
5702        } catch (ClassCastException e) {
5703        }
5704        return null;
5705    }
5706
5707    @Override
5708    public int getUidForIntentSender(IIntentSender sender) {
5709        if (sender instanceof PendingIntentRecord) {
5710            try {
5711                PendingIntentRecord res = (PendingIntentRecord)sender;
5712                return res.uid;
5713            } catch (ClassCastException e) {
5714            }
5715        }
5716        return -1;
5717    }
5718
5719    @Override
5720    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5721        if (!(pendingResult instanceof PendingIntentRecord)) {
5722            return false;
5723        }
5724        try {
5725            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5726            if (res.key.allIntents == null) {
5727                return false;
5728            }
5729            for (int i=0; i<res.key.allIntents.length; i++) {
5730                Intent intent = res.key.allIntents[i];
5731                if (intent.getPackage() != null && intent.getComponent() != null) {
5732                    return false;
5733                }
5734            }
5735            return true;
5736        } catch (ClassCastException e) {
5737        }
5738        return false;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5749                return true;
5750            }
5751            return false;
5752        } catch (ClassCastException e) {
5753        }
5754        return false;
5755    }
5756
5757    @Override
5758    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5759        if (!(pendingResult instanceof PendingIntentRecord)) {
5760            return null;
5761        }
5762        try {
5763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5764            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5765        } catch (ClassCastException e) {
5766        }
5767        return null;
5768    }
5769
5770    @Override
5771    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5772        if (!(pendingResult instanceof PendingIntentRecord)) {
5773            return null;
5774        }
5775        try {
5776            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5777            Intent intent = res.key.requestIntent;
5778            if (intent != null) {
5779                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5780                        || res.lastTagPrefix.equals(prefix))) {
5781                    return res.lastTag;
5782                }
5783                res.lastTagPrefix = prefix;
5784                StringBuilder sb = new StringBuilder(128);
5785                if (prefix != null) {
5786                    sb.append(prefix);
5787                }
5788                if (intent.getAction() != null) {
5789                    sb.append(intent.getAction());
5790                } else if (intent.getComponent() != null) {
5791                    intent.getComponent().appendShortString(sb);
5792                } else {
5793                    sb.append("?");
5794                }
5795                return res.lastTag = sb.toString();
5796            }
5797        } catch (ClassCastException e) {
5798        }
5799        return null;
5800    }
5801
5802    @Override
5803    public void setProcessLimit(int max) {
5804        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5805                "setProcessLimit()");
5806        synchronized (this) {
5807            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5808            mProcessLimitOverride = max;
5809        }
5810        trimApplications();
5811    }
5812
5813    @Override
5814    public int getProcessLimit() {
5815        synchronized (this) {
5816            return mProcessLimitOverride;
5817        }
5818    }
5819
5820    void foregroundTokenDied(ForegroundToken token) {
5821        synchronized (ActivityManagerService.this) {
5822            synchronized (mPidsSelfLocked) {
5823                ForegroundToken cur
5824                    = mForegroundProcesses.get(token.pid);
5825                if (cur != token) {
5826                    return;
5827                }
5828                mForegroundProcesses.remove(token.pid);
5829                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5830                if (pr == null) {
5831                    return;
5832                }
5833                pr.forcingToForeground = null;
5834                updateProcessForegroundLocked(pr, false, false);
5835            }
5836            updateOomAdjLocked();
5837        }
5838    }
5839
5840    @Override
5841    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5842        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5843                "setProcessForeground()");
5844        synchronized(this) {
5845            boolean changed = false;
5846
5847            synchronized (mPidsSelfLocked) {
5848                ProcessRecord pr = mPidsSelfLocked.get(pid);
5849                if (pr == null && isForeground) {
5850                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5851                    return;
5852                }
5853                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5854                if (oldToken != null) {
5855                    oldToken.token.unlinkToDeath(oldToken, 0);
5856                    mForegroundProcesses.remove(pid);
5857                    if (pr != null) {
5858                        pr.forcingToForeground = null;
5859                    }
5860                    changed = true;
5861                }
5862                if (isForeground && token != null) {
5863                    ForegroundToken newToken = new ForegroundToken() {
5864                        @Override
5865                        public void binderDied() {
5866                            foregroundTokenDied(this);
5867                        }
5868                    };
5869                    newToken.pid = pid;
5870                    newToken.token = token;
5871                    try {
5872                        token.linkToDeath(newToken, 0);
5873                        mForegroundProcesses.put(pid, newToken);
5874                        pr.forcingToForeground = token;
5875                        changed = true;
5876                    } catch (RemoteException e) {
5877                        // If the process died while doing this, we will later
5878                        // do the cleanup with the process death link.
5879                    }
5880                }
5881            }
5882
5883            if (changed) {
5884                updateOomAdjLocked();
5885            }
5886        }
5887    }
5888
5889    // =========================================================
5890    // PERMISSIONS
5891    // =========================================================
5892
5893    static class PermissionController extends IPermissionController.Stub {
5894        ActivityManagerService mActivityManagerService;
5895        PermissionController(ActivityManagerService activityManagerService) {
5896            mActivityManagerService = activityManagerService;
5897        }
5898
5899        @Override
5900        public boolean checkPermission(String permission, int pid, int uid) {
5901            return mActivityManagerService.checkPermission(permission, pid,
5902                    uid) == PackageManager.PERMISSION_GRANTED;
5903        }
5904    }
5905
5906    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5907        @Override
5908        public int checkComponentPermission(String permission, int pid, int uid,
5909                int owningUid, boolean exported) {
5910            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5911                    owningUid, exported);
5912        }
5913
5914        @Override
5915        public Object getAMSLock() {
5916            return ActivityManagerService.this;
5917        }
5918    }
5919
5920    /**
5921     * This can be called with or without the global lock held.
5922     */
5923    int checkComponentPermission(String permission, int pid, int uid,
5924            int owningUid, boolean exported) {
5925        // We might be performing an operation on behalf of an indirect binder
5926        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5927        // client identity accordingly before proceeding.
5928        Identity tlsIdentity = sCallerIdentity.get();
5929        if (tlsIdentity != null) {
5930            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5931                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5932            uid = tlsIdentity.uid;
5933            pid = tlsIdentity.pid;
5934        }
5935
5936        if (pid == MY_PID) {
5937            return PackageManager.PERMISSION_GRANTED;
5938        }
5939
5940        return ActivityManager.checkComponentPermission(permission, uid,
5941                owningUid, exported);
5942    }
5943
5944    /**
5945     * As the only public entry point for permissions checking, this method
5946     * can enforce the semantic that requesting a check on a null global
5947     * permission is automatically denied.  (Internally a null permission
5948     * string is used when calling {@link #checkComponentPermission} in cases
5949     * when only uid-based security is needed.)
5950     *
5951     * This can be called with or without the global lock held.
5952     */
5953    @Override
5954    public int checkPermission(String permission, int pid, int uid) {
5955        if (permission == null) {
5956            return PackageManager.PERMISSION_DENIED;
5957        }
5958        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5959    }
5960
5961    /**
5962     * Binder IPC calls go through the public entry point.
5963     * This can be called with or without the global lock held.
5964     */
5965    int checkCallingPermission(String permission) {
5966        return checkPermission(permission,
5967                Binder.getCallingPid(),
5968                UserHandle.getAppId(Binder.getCallingUid()));
5969    }
5970
5971    /**
5972     * This can be called with or without the global lock held.
5973     */
5974    void enforceCallingPermission(String permission, String func) {
5975        if (checkCallingPermission(permission)
5976                == PackageManager.PERMISSION_GRANTED) {
5977            return;
5978        }
5979
5980        String msg = "Permission Denial: " + func + " from pid="
5981                + Binder.getCallingPid()
5982                + ", uid=" + Binder.getCallingUid()
5983                + " requires " + permission;
5984        Slog.w(TAG, msg);
5985        throw new SecurityException(msg);
5986    }
5987
5988    /**
5989     * Determine if UID is holding permissions required to access {@link Uri} in
5990     * the given {@link ProviderInfo}. Final permission checking is always done
5991     * in {@link ContentProvider}.
5992     */
5993    private final boolean checkHoldingPermissionsLocked(
5994            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5995        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5996                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5997
5998        if (pi.applicationInfo.uid == uid) {
5999            return true;
6000        } else if (!pi.exported) {
6001            return false;
6002        }
6003
6004        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6005        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6006        try {
6007            // check if target holds top-level <provider> permissions
6008            if (!readMet && pi.readPermission != null
6009                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6010                readMet = true;
6011            }
6012            if (!writeMet && pi.writePermission != null
6013                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6014                writeMet = true;
6015            }
6016
6017            // track if unprotected read/write is allowed; any denied
6018            // <path-permission> below removes this ability
6019            boolean allowDefaultRead = pi.readPermission == null;
6020            boolean allowDefaultWrite = pi.writePermission == null;
6021
6022            // check if target holds any <path-permission> that match uri
6023            final PathPermission[] pps = pi.pathPermissions;
6024            if (pps != null) {
6025                final String path = uri.getPath();
6026                int i = pps.length;
6027                while (i > 0 && (!readMet || !writeMet)) {
6028                    i--;
6029                    PathPermission pp = pps[i];
6030                    if (pp.match(path)) {
6031                        if (!readMet) {
6032                            final String pprperm = pp.getReadPermission();
6033                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6034                                    + pprperm + " for " + pp.getPath()
6035                                    + ": match=" + pp.match(path)
6036                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6037                            if (pprperm != null) {
6038                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6039                                    readMet = true;
6040                                } else {
6041                                    allowDefaultRead = false;
6042                                }
6043                            }
6044                        }
6045                        if (!writeMet) {
6046                            final String ppwperm = pp.getWritePermission();
6047                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6048                                    + ppwperm + " for " + pp.getPath()
6049                                    + ": match=" + pp.match(path)
6050                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6051                            if (ppwperm != null) {
6052                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6053                                    writeMet = true;
6054                                } else {
6055                                    allowDefaultWrite = false;
6056                                }
6057                            }
6058                        }
6059                    }
6060                }
6061            }
6062
6063            // grant unprotected <provider> read/write, if not blocked by
6064            // <path-permission> above
6065            if (allowDefaultRead) readMet = true;
6066            if (allowDefaultWrite) writeMet = true;
6067
6068        } catch (RemoteException e) {
6069            return false;
6070        }
6071
6072        return readMet && writeMet;
6073    }
6074
6075    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6076        ProviderInfo pi = null;
6077        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6078        if (cpr != null) {
6079            pi = cpr.info;
6080        } else {
6081            try {
6082                pi = AppGlobals.getPackageManager().resolveContentProvider(
6083                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6084            } catch (RemoteException ex) {
6085            }
6086        }
6087        return pi;
6088    }
6089
6090    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6091        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6092        if (targetUris != null) {
6093            return targetUris.get(uri);
6094        }
6095        return null;
6096    }
6097
6098    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6099            String targetPkg, int targetUid, GrantUri uri) {
6100        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6101        if (targetUris == null) {
6102            targetUris = Maps.newArrayMap();
6103            mGrantedUriPermissions.put(targetUid, targetUris);
6104        }
6105
6106        UriPermission perm = targetUris.get(uri);
6107        if (perm == null) {
6108            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6109            targetUris.put(uri, perm);
6110        }
6111
6112        return perm;
6113    }
6114
6115    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6116        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6117        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6118                : UriPermission.STRENGTH_OWNED;
6119
6120        // Root gets to do everything.
6121        if (uid == 0) {
6122            return true;
6123        }
6124
6125        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6126        if (perms == null) return false;
6127
6128        // First look for exact match
6129        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6130        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6131            return true;
6132        }
6133
6134        // No exact match, look for prefixes
6135        final int N = perms.size();
6136        for (int i = 0; i < N; i++) {
6137            final UriPermission perm = perms.valueAt(i);
6138            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6139                    && perm.getStrength(modeFlags) >= minStrength) {
6140                return true;
6141            }
6142        }
6143
6144        return false;
6145    }
6146
6147    @Override
6148    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6149        enforceNotIsolatedCaller("checkUriPermission");
6150
6151        // Another redirected-binder-call permissions check as in
6152        // {@link checkComponentPermission}.
6153        Identity tlsIdentity = sCallerIdentity.get();
6154        if (tlsIdentity != null) {
6155            uid = tlsIdentity.uid;
6156            pid = tlsIdentity.pid;
6157        }
6158
6159        // Our own process gets to do everything.
6160        if (pid == MY_PID) {
6161            return PackageManager.PERMISSION_GRANTED;
6162        }
6163        synchronized (this) {
6164            return checkUriPermissionLocked(uri, uid, modeFlags)
6165                    ? PackageManager.PERMISSION_GRANTED
6166                    : PackageManager.PERMISSION_DENIED;
6167        }
6168    }
6169
6170    /**
6171     * Check if the targetPkg can be granted permission to access uri by
6172     * the callingUid using the given modeFlags.  Throws a security exception
6173     * if callingUid is not allowed to do this.  Returns the uid of the target
6174     * if the URI permission grant should be performed; returns -1 if it is not
6175     * needed (for example targetPkg already has permission to access the URI).
6176     * If you already know the uid of the target, you can supply it in
6177     * lastTargetUid else set that to -1.
6178     */
6179    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6180            Uri uri, final int modeFlags, int lastTargetUid) {
6181        if (!Intent.isAccessUriMode(modeFlags)) {
6182            return -1;
6183        }
6184
6185        if (targetPkg != null) {
6186            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6187                    "Checking grant " + targetPkg + " permission to " + uri);
6188        }
6189
6190        final IPackageManager pm = AppGlobals.getPackageManager();
6191
6192        // If this is not a content: uri, we can't do anything with it.
6193        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6194            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6195                    "Can't grant URI permission for non-content URI: " + uri);
6196            return -1;
6197        }
6198
6199        final String authority = uri.getAuthority();
6200        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6201        if (pi == null) {
6202            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6203            return -1;
6204        }
6205
6206        int targetUid = lastTargetUid;
6207        if (targetUid < 0 && targetPkg != null) {
6208            try {
6209                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6210                if (targetUid < 0) {
6211                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                            "Can't grant URI permission no uid for: " + targetPkg);
6213                    return -1;
6214                }
6215            } catch (RemoteException ex) {
6216                return -1;
6217            }
6218        }
6219
6220        if (targetUid >= 0) {
6221            // First...  does the target actually need this permission?
6222            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6223                // No need to grant the target this permission.
6224                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6225                        "Target " + targetPkg + " already has full permission to " + uri);
6226                return -1;
6227            }
6228        } else {
6229            // First...  there is no target package, so can anyone access it?
6230            boolean allowed = pi.exported;
6231            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6232                if (pi.readPermission != null) {
6233                    allowed = false;
6234                }
6235            }
6236            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6237                if (pi.writePermission != null) {
6238                    allowed = false;
6239                }
6240            }
6241            if (allowed) {
6242                return -1;
6243            }
6244        }
6245
6246        // Second...  is the provider allowing granting of URI permissions?
6247        if (!pi.grantUriPermissions) {
6248            throw new SecurityException("Provider " + pi.packageName
6249                    + "/" + pi.name
6250                    + " does not allow granting of Uri permissions (uri "
6251                    + uri + ")");
6252        }
6253        if (pi.uriPermissionPatterns != null) {
6254            final int N = pi.uriPermissionPatterns.length;
6255            boolean allowed = false;
6256            for (int i=0; i<N; i++) {
6257                if (pi.uriPermissionPatterns[i] != null
6258                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6259                    allowed = true;
6260                    break;
6261                }
6262            }
6263            if (!allowed) {
6264                throw new SecurityException("Provider " + pi.packageName
6265                        + "/" + pi.name
6266                        + " does not allow granting of permission to path of Uri "
6267                        + uri);
6268            }
6269        }
6270
6271        // Third...  does the caller itself have permission to access
6272        // this uri?
6273        if (callingUid != Process.myUid()) {
6274            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6275                // Require they hold a strong enough Uri permission
6276                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6277                    throw new SecurityException("Uid " + callingUid
6278                            + " does not have permission to uri " + uri);
6279                }
6280            }
6281        }
6282
6283        return targetUid;
6284    }
6285
6286    @Override
6287    public int checkGrantUriPermission(int callingUid, String targetPkg,
6288            Uri uri, final int modeFlags) {
6289        enforceNotIsolatedCaller("checkGrantUriPermission");
6290        synchronized(this) {
6291            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6292        }
6293    }
6294
6295    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6296            final int modeFlags, UriPermissionOwner owner) {
6297        if (!Intent.isAccessUriMode(modeFlags)) {
6298            return;
6299        }
6300
6301        // So here we are: the caller has the assumed permission
6302        // to the uri, and the target doesn't.  Let's now give this to
6303        // the target.
6304
6305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6306                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6307
6308        final String authority = uri.getAuthority();
6309        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6310        if (pi == null) {
6311            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6312            return;
6313        }
6314
6315        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6316        final UriPermission perm = findOrCreateUriPermissionLocked(
6317                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6318        perm.grantModes(modeFlags, owner);
6319    }
6320
6321    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6322            final int modeFlags, UriPermissionOwner owner) {
6323        if (targetPkg == null) {
6324            throw new NullPointerException("targetPkg");
6325        }
6326
6327        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6328        if (targetUid < 0) {
6329            return;
6330        }
6331
6332        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6333    }
6334
6335    static class NeededUriGrants extends ArrayList<Uri> {
6336        final String targetPkg;
6337        final int targetUid;
6338        final int flags;
6339
6340        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6341            this.targetPkg = targetPkg;
6342            this.targetUid = targetUid;
6343            this.flags = flags;
6344        }
6345    }
6346
6347    /**
6348     * Like checkGrantUriPermissionLocked, but takes an Intent.
6349     */
6350    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6351            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6352        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6353                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6354                + " clip=" + (intent != null ? intent.getClipData() : null)
6355                + " from " + intent + "; flags=0x"
6356                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6357
6358        if (targetPkg == null) {
6359            throw new NullPointerException("targetPkg");
6360        }
6361
6362        if (intent == null) {
6363            return null;
6364        }
6365        Uri data = intent.getData();
6366        ClipData clip = intent.getClipData();
6367        if (data == null && clip == null) {
6368            return null;
6369        }
6370
6371        if (data != null) {
6372            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6373                mode, needed != null ? needed.targetUid : -1);
6374            if (targetUid > 0) {
6375                if (needed == null) {
6376                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6377                }
6378                needed.add(data);
6379            }
6380        }
6381        if (clip != null) {
6382            for (int i=0; i<clip.getItemCount(); i++) {
6383                Uri uri = clip.getItemAt(i).getUri();
6384                if (uri != null) {
6385                    int targetUid = -1;
6386                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6387                            mode, needed != null ? needed.targetUid : -1);
6388                    if (targetUid > 0) {
6389                        if (needed == null) {
6390                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6391                        }
6392                        needed.add(uri);
6393                    }
6394                } else {
6395                    Intent clipIntent = clip.getItemAt(i).getIntent();
6396                    if (clipIntent != null) {
6397                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6398                                callingUid, targetPkg, clipIntent, mode, needed);
6399                        if (newNeeded != null) {
6400                            needed = newNeeded;
6401                        }
6402                    }
6403                }
6404            }
6405        }
6406
6407        return needed;
6408    }
6409
6410    /**
6411     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6412     */
6413    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6414            UriPermissionOwner owner) {
6415        if (needed != null) {
6416            for (int i=0; i<needed.size(); i++) {
6417                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6418                        needed.get(i), needed.flags, owner);
6419            }
6420        }
6421    }
6422
6423    void grantUriPermissionFromIntentLocked(int callingUid,
6424            String targetPkg, Intent intent, UriPermissionOwner owner) {
6425        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6426                intent, intent != null ? intent.getFlags() : 0, null);
6427        if (needed == null) {
6428            return;
6429        }
6430
6431        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6432    }
6433
6434    @Override
6435    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6436            Uri uri, final int modeFlags) {
6437        enforceNotIsolatedCaller("grantUriPermission");
6438        synchronized(this) {
6439            final ProcessRecord r = getRecordForAppLocked(caller);
6440            if (r == null) {
6441                throw new SecurityException("Unable to find app for caller "
6442                        + caller
6443                        + " when granting permission to uri " + uri);
6444            }
6445            if (targetPkg == null) {
6446                throw new IllegalArgumentException("null target");
6447            }
6448            if (uri == null) {
6449                throw new IllegalArgumentException("null uri");
6450            }
6451
6452            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6453                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6454                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6455                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6456
6457            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6458        }
6459    }
6460
6461    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6462        if (perm.modeFlags == 0) {
6463            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6464                    perm.targetUid);
6465            if (perms != null) {
6466                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6467                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6468
6469                perms.remove(perm.uri);
6470                if (perms.isEmpty()) {
6471                    mGrantedUriPermissions.remove(perm.targetUid);
6472                }
6473            }
6474        }
6475    }
6476
6477    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6478        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6479
6480        final IPackageManager pm = AppGlobals.getPackageManager();
6481        final String authority = uri.getAuthority();
6482        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6483        if (pi == null) {
6484            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6485            return;
6486        }
6487
6488        // Does the caller have this permission on the URI?
6489        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6490            // Right now, if you are not the original owner of the permission,
6491            // you are not allowed to revoke it.
6492            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6493                throw new SecurityException("Uid " + callingUid
6494                        + " does not have permission to uri " + uri);
6495            //}
6496        }
6497
6498        boolean persistChanged = false;
6499
6500        // Go through all of the permissions and remove any that match.
6501        int N = mGrantedUriPermissions.size();
6502        for (int i = 0; i < N; i++) {
6503            final int targetUid = mGrantedUriPermissions.keyAt(i);
6504            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6505
6506            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6507                final UriPermission perm = it.next();
6508                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6509                    if (DEBUG_URI_PERMISSION)
6510                        Slog.v(TAG,
6511                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6512                    persistChanged |= perm.revokeModes(
6513                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6514                    if (perm.modeFlags == 0) {
6515                        it.remove();
6516                    }
6517                }
6518            }
6519
6520            if (perms.isEmpty()) {
6521                mGrantedUriPermissions.remove(targetUid);
6522                N--;
6523                i--;
6524            }
6525        }
6526
6527        if (persistChanged) {
6528            schedulePersistUriGrants();
6529        }
6530    }
6531
6532    @Override
6533    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6534            final int modeFlags) {
6535        enforceNotIsolatedCaller("revokeUriPermission");
6536        synchronized(this) {
6537            final ProcessRecord r = getRecordForAppLocked(caller);
6538            if (r == null) {
6539                throw new SecurityException("Unable to find app for caller "
6540                        + caller
6541                        + " when revoking permission to uri " + uri);
6542            }
6543            if (uri == null) {
6544                Slog.w(TAG, "revokeUriPermission: null uri");
6545                return;
6546            }
6547
6548            if (!Intent.isAccessUriMode(modeFlags)) {
6549                return;
6550            }
6551
6552            final IPackageManager pm = AppGlobals.getPackageManager();
6553            final String authority = uri.getAuthority();
6554            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6555            if (pi == null) {
6556                Slog.w(TAG, "No content provider found for permission revoke: "
6557                        + uri.toSafeString());
6558                return;
6559            }
6560
6561            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6562        }
6563    }
6564
6565    /**
6566     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6567     * given package.
6568     *
6569     * @param packageName Package name to match, or {@code null} to apply to all
6570     *            packages.
6571     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6572     *            to all users.
6573     * @param persistable If persistable grants should be removed.
6574     */
6575    private void removeUriPermissionsForPackageLocked(
6576            String packageName, int userHandle, boolean persistable) {
6577        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6578            throw new IllegalArgumentException("Must narrow by either package or user");
6579        }
6580
6581        boolean persistChanged = false;
6582
6583        int N = mGrantedUriPermissions.size();
6584        for (int i = 0; i < N; i++) {
6585            final int targetUid = mGrantedUriPermissions.keyAt(i);
6586            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6587
6588            // Only inspect grants matching user
6589            if (userHandle == UserHandle.USER_ALL
6590                    || userHandle == UserHandle.getUserId(targetUid)) {
6591                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6592                    final UriPermission perm = it.next();
6593
6594                    // Only inspect grants matching package
6595                    if (packageName == null || perm.sourcePkg.equals(packageName)
6596                            || perm.targetPkg.equals(packageName)) {
6597                        persistChanged |= perm.revokeModes(
6598                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6599
6600                        // Only remove when no modes remain; any persisted grants
6601                        // will keep this alive.
6602                        if (perm.modeFlags == 0) {
6603                            it.remove();
6604                        }
6605                    }
6606                }
6607
6608                if (perms.isEmpty()) {
6609                    mGrantedUriPermissions.remove(targetUid);
6610                    N--;
6611                    i--;
6612                }
6613            }
6614        }
6615
6616        if (persistChanged) {
6617            schedulePersistUriGrants();
6618        }
6619    }
6620
6621    @Override
6622    public IBinder newUriPermissionOwner(String name) {
6623        enforceNotIsolatedCaller("newUriPermissionOwner");
6624        synchronized(this) {
6625            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6626            return owner.getExternalTokenLocked();
6627        }
6628    }
6629
6630    @Override
6631    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6632            Uri uri, final int modeFlags) {
6633        synchronized(this) {
6634            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6635            if (owner == null) {
6636                throw new IllegalArgumentException("Unknown owner: " + token);
6637            }
6638            if (fromUid != Binder.getCallingUid()) {
6639                if (Binder.getCallingUid() != Process.myUid()) {
6640                    // Only system code can grant URI permissions on behalf
6641                    // of other users.
6642                    throw new SecurityException("nice try");
6643                }
6644            }
6645            if (targetPkg == null) {
6646                throw new IllegalArgumentException("null target");
6647            }
6648            if (uri == null) {
6649                throw new IllegalArgumentException("null uri");
6650            }
6651
6652            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6653        }
6654    }
6655
6656    @Override
6657    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6658        synchronized(this) {
6659            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6660            if (owner == null) {
6661                throw new IllegalArgumentException("Unknown owner: " + token);
6662            }
6663
6664            if (uri == null) {
6665                owner.removeUriPermissionsLocked(mode);
6666            } else {
6667                owner.removeUriPermissionLocked(uri, mode);
6668            }
6669        }
6670    }
6671
6672    private void schedulePersistUriGrants() {
6673        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6674            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6675                    10 * DateUtils.SECOND_IN_MILLIS);
6676        }
6677    }
6678
6679    private void writeGrantedUriPermissions() {
6680        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6681
6682        // Snapshot permissions so we can persist without lock
6683        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6684        synchronized (this) {
6685            final int size = mGrantedUriPermissions.size();
6686            for (int i = 0; i < size; i++) {
6687                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6688                for (UriPermission perm : perms.values()) {
6689                    if (perm.persistedModeFlags != 0) {
6690                        persist.add(perm.snapshot());
6691                    }
6692                }
6693            }
6694        }
6695
6696        FileOutputStream fos = null;
6697        try {
6698            fos = mGrantFile.startWrite();
6699
6700            XmlSerializer out = new FastXmlSerializer();
6701            out.setOutput(fos, "utf-8");
6702            out.startDocument(null, true);
6703            out.startTag(null, TAG_URI_GRANTS);
6704            for (UriPermission.Snapshot perm : persist) {
6705                out.startTag(null, TAG_URI_GRANT);
6706                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6707                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6708                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6709                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6710                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6711                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6712                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6713                out.endTag(null, TAG_URI_GRANT);
6714            }
6715            out.endTag(null, TAG_URI_GRANTS);
6716            out.endDocument();
6717
6718            mGrantFile.finishWrite(fos);
6719        } catch (IOException e) {
6720            if (fos != null) {
6721                mGrantFile.failWrite(fos);
6722            }
6723        }
6724    }
6725
6726    private void readGrantedUriPermissionsLocked() {
6727        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6728
6729        final long now = System.currentTimeMillis();
6730
6731        FileInputStream fis = null;
6732        try {
6733            fis = mGrantFile.openRead();
6734            final XmlPullParser in = Xml.newPullParser();
6735            in.setInput(fis, null);
6736
6737            int type;
6738            while ((type = in.next()) != END_DOCUMENT) {
6739                final String tag = in.getName();
6740                if (type == START_TAG) {
6741                    if (TAG_URI_GRANT.equals(tag)) {
6742                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6743                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6744                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6745                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6746                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6747                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6748                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6749
6750                        // Sanity check that provider still belongs to source package
6751                        final ProviderInfo pi = getProviderInfoLocked(
6752                                uri.getAuthority(), userHandle);
6753                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6754                            int targetUid = -1;
6755                            try {
6756                                targetUid = AppGlobals.getPackageManager()
6757                                        .getPackageUid(targetPkg, userHandle);
6758                            } catch (RemoteException e) {
6759                            }
6760                            if (targetUid != -1) {
6761                                final UriPermission perm = findOrCreateUriPermissionLocked(
6762                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6763                                perm.initPersistedModes(modeFlags, createdTime);
6764                            }
6765                        } else {
6766                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6767                                    + " but instead found " + pi);
6768                        }
6769                    }
6770                }
6771            }
6772        } catch (FileNotFoundException e) {
6773            // Missing grants is okay
6774        } catch (IOException e) {
6775            Log.wtf(TAG, "Failed reading Uri grants", e);
6776        } catch (XmlPullParserException e) {
6777            Log.wtf(TAG, "Failed reading Uri grants", e);
6778        } finally {
6779            IoUtils.closeQuietly(fis);
6780        }
6781    }
6782
6783    @Override
6784    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6785        enforceNotIsolatedCaller("takePersistableUriPermission");
6786
6787        Preconditions.checkFlagsArgument(modeFlags,
6788                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6789
6790        synchronized (this) {
6791            final int callingUid = Binder.getCallingUid();
6792            boolean persistChanged = false;
6793
6794            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6795            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6796
6797            final boolean exactValid = (exactPerm != null)
6798                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6799            final boolean prefixValid = (prefixPerm != null)
6800                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6801
6802            if (!(exactValid || prefixValid)) {
6803                throw new SecurityException("No persistable permission grants found for UID "
6804                        + callingUid + " and Uri " + uri.toSafeString());
6805            }
6806
6807            if (exactValid) {
6808                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6809            }
6810            if (prefixValid) {
6811                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6812            }
6813
6814            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6815
6816            if (persistChanged) {
6817                schedulePersistUriGrants();
6818            }
6819        }
6820    }
6821
6822    @Override
6823    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6824        enforceNotIsolatedCaller("releasePersistableUriPermission");
6825
6826        Preconditions.checkFlagsArgument(modeFlags,
6827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6828
6829        synchronized (this) {
6830            final int callingUid = Binder.getCallingUid();
6831            boolean persistChanged = false;
6832
6833            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6834            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6835            if (exactPerm == null && prefixPerm == null) {
6836                throw new SecurityException("No permission grants found for UID " + callingUid
6837                        + " and Uri " + uri.toSafeString());
6838            }
6839
6840            if (exactPerm != null) {
6841                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6842                removeUriPermissionIfNeededLocked(exactPerm);
6843            }
6844            if (prefixPerm != null) {
6845                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6846                removeUriPermissionIfNeededLocked(prefixPerm);
6847            }
6848
6849            if (persistChanged) {
6850                schedulePersistUriGrants();
6851            }
6852        }
6853    }
6854
6855    /**
6856     * Prune any older {@link UriPermission} for the given UID until outstanding
6857     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6858     *
6859     * @return if any mutations occured that require persisting.
6860     */
6861    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6862        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6863        if (perms == null) return false;
6864        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6865
6866        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6867        for (UriPermission perm : perms.values()) {
6868            if (perm.persistedModeFlags != 0) {
6869                persisted.add(perm);
6870            }
6871        }
6872
6873        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6874        if (trimCount <= 0) return false;
6875
6876        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6877        for (int i = 0; i < trimCount; i++) {
6878            final UriPermission perm = persisted.get(i);
6879
6880            if (DEBUG_URI_PERMISSION) {
6881                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6882            }
6883
6884            perm.releasePersistableModes(~0);
6885            removeUriPermissionIfNeededLocked(perm);
6886        }
6887
6888        return true;
6889    }
6890
6891    @Override
6892    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6893            String packageName, boolean incoming) {
6894        enforceNotIsolatedCaller("getPersistedUriPermissions");
6895        Preconditions.checkNotNull(packageName, "packageName");
6896
6897        final int callingUid = Binder.getCallingUid();
6898        final IPackageManager pm = AppGlobals.getPackageManager();
6899        try {
6900            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6901            if (packageUid != callingUid) {
6902                throw new SecurityException(
6903                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6904            }
6905        } catch (RemoteException e) {
6906            throw new SecurityException("Failed to verify package name ownership");
6907        }
6908
6909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6910        synchronized (this) {
6911            if (incoming) {
6912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6913                        callingUid);
6914                if (perms == null) {
6915                    Slog.w(TAG, "No permission grants found for " + packageName);
6916                } else {
6917                    for (UriPermission perm : perms.values()) {
6918                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6919                            result.add(perm.buildPersistedPublicApiObject());
6920                        }
6921                    }
6922                }
6923            } else {
6924                final int size = mGrantedUriPermissions.size();
6925                for (int i = 0; i < size; i++) {
6926                    final ArrayMap<GrantUri, UriPermission> perms =
6927                            mGrantedUriPermissions.valueAt(i);
6928                    for (UriPermission perm : perms.values()) {
6929                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6930                            result.add(perm.buildPersistedPublicApiObject());
6931                        }
6932                    }
6933                }
6934            }
6935        }
6936        return new ParceledListSlice<android.content.UriPermission>(result);
6937    }
6938
6939    @Override
6940    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6941        synchronized (this) {
6942            ProcessRecord app =
6943                who != null ? getRecordForAppLocked(who) : null;
6944            if (app == null) return;
6945
6946            Message msg = Message.obtain();
6947            msg.what = WAIT_FOR_DEBUGGER_MSG;
6948            msg.obj = app;
6949            msg.arg1 = waiting ? 1 : 0;
6950            mHandler.sendMessage(msg);
6951        }
6952    }
6953
6954    @Override
6955    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6956        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6957        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6958        outInfo.availMem = Process.getFreeMemory();
6959        outInfo.totalMem = Process.getTotalMemory();
6960        outInfo.threshold = homeAppMem;
6961        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6962        outInfo.hiddenAppThreshold = cachedAppMem;
6963        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6964                ProcessList.SERVICE_ADJ);
6965        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6966                ProcessList.VISIBLE_APP_ADJ);
6967        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6968                ProcessList.FOREGROUND_APP_ADJ);
6969    }
6970
6971    // =========================================================
6972    // TASK MANAGEMENT
6973    // =========================================================
6974
6975    @Override
6976    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6977        final int callingUid = Binder.getCallingUid();
6978        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6979
6980        synchronized(this) {
6981            if (localLOGV) Slog.v(
6982                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6983
6984            final boolean allowed = checkCallingPermission(
6985                    android.Manifest.permission.GET_TASKS)
6986                    == PackageManager.PERMISSION_GRANTED;
6987            if (!allowed) {
6988                Slog.w(TAG, "getTasks: caller " + callingUid
6989                        + " does not hold GET_TASKS; limiting output");
6990            }
6991
6992            // TODO: Improve with MRU list from all ActivityStacks.
6993            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6994        }
6995
6996        return list;
6997    }
6998
6999    TaskRecord getMostRecentTask() {
7000        return mRecentTasks.get(0);
7001    }
7002
7003    @Override
7004    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7005            int flags, int userId) {
7006        final int callingUid = Binder.getCallingUid();
7007        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7008                false, true, "getRecentTasks", null);
7009
7010        synchronized (this) {
7011            final boolean allowed = checkCallingPermission(
7012                    android.Manifest.permission.GET_TASKS)
7013                    == PackageManager.PERMISSION_GRANTED;
7014            if (!allowed) {
7015                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7016                        + " does not hold GET_TASKS; limiting output");
7017            }
7018            final boolean detailed = checkCallingPermission(
7019                    android.Manifest.permission.GET_DETAILED_TASKS)
7020                    == PackageManager.PERMISSION_GRANTED;
7021
7022            IPackageManager pm = AppGlobals.getPackageManager();
7023
7024            final int N = mRecentTasks.size();
7025            ArrayList<ActivityManager.RecentTaskInfo> res
7026                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7027                            maxNum < N ? maxNum : N);
7028
7029            final Set<Integer> includedUsers;
7030            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7031                includedUsers = getProfileIdsLocked(userId);
7032            } else {
7033                includedUsers = new HashSet<Integer>();
7034            }
7035            includedUsers.add(Integer.valueOf(userId));
7036            for (int i=0; i<N && maxNum > 0; i++) {
7037                TaskRecord tr = mRecentTasks.get(i);
7038                // Only add calling user or related users recent tasks
7039                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7040
7041                // Return the entry if desired by the caller.  We always return
7042                // the first entry, because callers always expect this to be the
7043                // foreground app.  We may filter others if the caller has
7044                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7045                // we should exclude the entry.
7046
7047                if (i == 0
7048                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7049                        || (tr.intent == null)
7050                        || ((tr.intent.getFlags()
7051                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7052                    if (!allowed) {
7053                        // If the caller doesn't have the GET_TASKS permission, then only
7054                        // allow them to see a small subset of tasks -- their own and home.
7055                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7056                            continue;
7057                        }
7058                    }
7059                    ActivityManager.RecentTaskInfo rti
7060                            = new ActivityManager.RecentTaskInfo();
7061                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7062                    rti.persistentId = tr.taskId;
7063                    rti.baseIntent = new Intent(
7064                            tr.intent != null ? tr.intent : tr.affinityIntent);
7065                    if (!detailed) {
7066                        rti.baseIntent.replaceExtras((Bundle)null);
7067                    }
7068                    rti.origActivity = tr.origActivity;
7069                    rti.description = tr.lastDescription;
7070                    rti.stackId = tr.stack.mStackId;
7071                    rti.userId = tr.userId;
7072
7073                    // Traverse upwards looking for any break between main task activities and
7074                    // utility activities.
7075                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7076                    int activityNdx;
7077                    final int numActivities = activities.size();
7078                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7079                            ++activityNdx) {
7080                        final ActivityRecord r = activities.get(activityNdx);
7081                        if (r.intent != null &&
7082                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7083                                        != 0) {
7084                            break;
7085                        }
7086                    }
7087                    if (activityNdx > 0) {
7088                        // Traverse downwards starting below break looking for set label, icon.
7089                        // Note that if there are activities in the task but none of them set the
7090                        // recent activity values, then we do not fall back to the last set
7091                        // values in the TaskRecord.
7092                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7093                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7094                            final ActivityRecord r = activities.get(activityNdx);
7095                            if (r.activityValues != null) {
7096                                if (rti.activityValues.label == null) {
7097                                    rti.activityValues.label = r.activityValues.label;
7098                                    tr.lastActivityValues.label = r.activityValues.label;
7099                                }
7100                                if (rti.activityValues.icon == null) {
7101                                    rti.activityValues.icon = r.activityValues.icon;
7102                                    tr.lastActivityValues.icon = r.activityValues.icon;
7103                                }
7104                                if (rti.activityValues.colorPrimary == 0) {
7105                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7106                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7107                                }
7108                            }
7109                        }
7110                    } else {
7111                        // If there are no activity records in this task, then we use the last
7112                        // resolved values
7113                        rti.activityValues =
7114                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7115                    }
7116
7117                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7118                        // Check whether this activity is currently available.
7119                        try {
7120                            if (rti.origActivity != null) {
7121                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7122                                        == null) {
7123                                    continue;
7124                                }
7125                            } else if (rti.baseIntent != null) {
7126                                if (pm.queryIntentActivities(rti.baseIntent,
7127                                        null, 0, userId) == null) {
7128                                    continue;
7129                                }
7130                            }
7131                        } catch (RemoteException e) {
7132                            // Will never happen.
7133                        }
7134                    }
7135
7136                    res.add(rti);
7137                    maxNum--;
7138                }
7139            }
7140            return res;
7141        }
7142    }
7143
7144    private TaskRecord recentTaskForIdLocked(int id) {
7145        final int N = mRecentTasks.size();
7146            for (int i=0; i<N; i++) {
7147                TaskRecord tr = mRecentTasks.get(i);
7148                if (tr.taskId == id) {
7149                    return tr;
7150                }
7151            }
7152            return null;
7153    }
7154
7155    @Override
7156    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7157        synchronized (this) {
7158            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7159                    "getTaskThumbnails()");
7160            TaskRecord tr = recentTaskForIdLocked(id);
7161            if (tr != null) {
7162                return tr.getTaskThumbnailsLocked();
7163            }
7164        }
7165        return null;
7166    }
7167
7168    @Override
7169    public Bitmap getTaskTopThumbnail(int id) {
7170        synchronized (this) {
7171            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7172                    "getTaskTopThumbnail()");
7173            TaskRecord tr = recentTaskForIdLocked(id);
7174            if (tr != null) {
7175                return tr.getTaskTopThumbnailLocked();
7176            }
7177        }
7178        return null;
7179    }
7180
7181    @Override
7182    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7183        synchronized (this) {
7184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7185            if (r != null) {
7186                r.activityValues = rav;
7187            }
7188        }
7189    }
7190
7191    @Override
7192    public boolean removeSubTask(int taskId, int subTaskIndex) {
7193        synchronized (this) {
7194            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7195                    "removeSubTask()");
7196            long ident = Binder.clearCallingIdentity();
7197            try {
7198                TaskRecord tr = recentTaskForIdLocked(taskId);
7199                if (tr != null) {
7200                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7201                }
7202                return false;
7203            } finally {
7204                Binder.restoreCallingIdentity(ident);
7205            }
7206        }
7207    }
7208
7209    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7210        if (!pr.killedByAm) {
7211            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7212            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7213                    pr.processName, pr.setAdj, reason);
7214            pr.killedByAm = true;
7215            Process.killProcessQuiet(pr.pid);
7216        }
7217    }
7218
7219    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7220        tr.disposeThumbnail();
7221        mRecentTasks.remove(tr);
7222        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7223        Intent baseIntent = new Intent(
7224                tr.intent != null ? tr.intent : tr.affinityIntent);
7225        ComponentName component = baseIntent.getComponent();
7226        if (component == null) {
7227            Slog.w(TAG, "Now component for base intent of task: " + tr);
7228            return;
7229        }
7230
7231        // Find any running services associated with this app.
7232        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7233
7234        if (killProcesses) {
7235            // Find any running processes associated with this app.
7236            final String pkg = component.getPackageName();
7237            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7238            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7239            for (int i=0; i<pmap.size(); i++) {
7240                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7241                for (int j=0; j<uids.size(); j++) {
7242                    ProcessRecord proc = uids.valueAt(j);
7243                    if (proc.userId != tr.userId) {
7244                        continue;
7245                    }
7246                    if (!proc.pkgList.containsKey(pkg)) {
7247                        continue;
7248                    }
7249                    procs.add(proc);
7250                }
7251            }
7252
7253            // Kill the running processes.
7254            for (int i=0; i<procs.size(); i++) {
7255                ProcessRecord pr = procs.get(i);
7256                if (pr == mHomeProcess) {
7257                    // Don't kill the home process along with tasks from the same package.
7258                    continue;
7259                }
7260                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7261                    killUnneededProcessLocked(pr, "remove task");
7262                } else {
7263                    pr.waitingToKill = "remove task";
7264                }
7265            }
7266        }
7267    }
7268
7269    /**
7270     * Removes the task with the specified task id.
7271     *
7272     * @param taskId Identifier of the task to be removed.
7273     * @param flags Additional operational flags.  May be 0 or
7274     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7275     * @return Returns true if the given task was found and removed.
7276     */
7277    private boolean removeTaskByIdLocked(int taskId, int flags) {
7278        TaskRecord tr = recentTaskForIdLocked(taskId);
7279        if (tr != null) {
7280            tr.removeTaskActivitiesLocked(-1, false);
7281            cleanUpRemovedTaskLocked(tr, flags);
7282            return true;
7283        }
7284        return false;
7285    }
7286
7287    @Override
7288    public boolean removeTask(int taskId, int flags) {
7289        synchronized (this) {
7290            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7291                    "removeTask()");
7292            long ident = Binder.clearCallingIdentity();
7293            try {
7294                return removeTaskByIdLocked(taskId, flags);
7295            } finally {
7296                Binder.restoreCallingIdentity(ident);
7297            }
7298        }
7299    }
7300
7301    /**
7302     * TODO: Add mController hook
7303     */
7304    @Override
7305    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7306        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7307                "moveTaskToFront()");
7308
7309        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7310        synchronized(this) {
7311            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7312                    Binder.getCallingUid(), "Task to front")) {
7313                ActivityOptions.abort(options);
7314                return;
7315            }
7316            final long origId = Binder.clearCallingIdentity();
7317            try {
7318                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7319                if (task == null) {
7320                    return;
7321                }
7322                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7323                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7324                    return;
7325                }
7326                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7327            } finally {
7328                Binder.restoreCallingIdentity(origId);
7329            }
7330            ActivityOptions.abort(options);
7331        }
7332    }
7333
7334    @Override
7335    public void moveTaskToBack(int taskId) {
7336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7337                "moveTaskToBack()");
7338
7339        synchronized(this) {
7340            TaskRecord tr = recentTaskForIdLocked(taskId);
7341            if (tr != null) {
7342                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7343                ActivityStack stack = tr.stack;
7344                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7345                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7346                            Binder.getCallingUid(), "Task to back")) {
7347                        return;
7348                    }
7349                }
7350                final long origId = Binder.clearCallingIdentity();
7351                try {
7352                    stack.moveTaskToBackLocked(taskId, null);
7353                } finally {
7354                    Binder.restoreCallingIdentity(origId);
7355                }
7356            }
7357        }
7358    }
7359
7360    /**
7361     * Moves an activity, and all of the other activities within the same task, to the bottom
7362     * of the history stack.  The activity's order within the task is unchanged.
7363     *
7364     * @param token A reference to the activity we wish to move
7365     * @param nonRoot If false then this only works if the activity is the root
7366     *                of a task; if true it will work for any activity in a task.
7367     * @return Returns true if the move completed, false if not.
7368     */
7369    @Override
7370    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7371        enforceNotIsolatedCaller("moveActivityTaskToBack");
7372        synchronized(this) {
7373            final long origId = Binder.clearCallingIdentity();
7374            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7375            if (taskId >= 0) {
7376                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7377            }
7378            Binder.restoreCallingIdentity(origId);
7379        }
7380        return false;
7381    }
7382
7383    @Override
7384    public void moveTaskBackwards(int task) {
7385        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7386                "moveTaskBackwards()");
7387
7388        synchronized(this) {
7389            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7390                    Binder.getCallingUid(), "Task backwards")) {
7391                return;
7392            }
7393            final long origId = Binder.clearCallingIdentity();
7394            moveTaskBackwardsLocked(task);
7395            Binder.restoreCallingIdentity(origId);
7396        }
7397    }
7398
7399    private final void moveTaskBackwardsLocked(int task) {
7400        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7401    }
7402
7403    @Override
7404    public IBinder getHomeActivityToken() throws RemoteException {
7405        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7406                "getHomeActivityToken()");
7407        synchronized (this) {
7408            return mStackSupervisor.getHomeActivityToken();
7409        }
7410    }
7411
7412    @Override
7413    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7414            IActivityContainerCallback callback) throws RemoteException {
7415        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7416                "createActivityContainer()");
7417        synchronized (this) {
7418            if (parentActivityToken == null) {
7419                throw new IllegalArgumentException("parent token must not be null");
7420            }
7421            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7422            if (r == null) {
7423                return null;
7424            }
7425            if (callback == null) {
7426                throw new IllegalArgumentException("callback must not be null");
7427            }
7428            return mStackSupervisor.createActivityContainer(r, callback);
7429        }
7430    }
7431
7432    @Override
7433    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7434        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7435                "deleteActivityContainer()");
7436        synchronized (this) {
7437            mStackSupervisor.deleteActivityContainer(container);
7438        }
7439    }
7440
7441    @Override
7442    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7443            throws RemoteException {
7444        synchronized (this) {
7445            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7446            if (stack != null) {
7447                return stack.mActivityContainer;
7448            }
7449            return null;
7450        }
7451    }
7452
7453    @Override
7454    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "moveTaskToStack()");
7457        if (stackId == HOME_STACK_ID) {
7458            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7459                    new RuntimeException("here").fillInStackTrace());
7460        }
7461        synchronized (this) {
7462            long ident = Binder.clearCallingIdentity();
7463            try {
7464                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7465                        + stackId + " toTop=" + toTop);
7466                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7467            } finally {
7468                Binder.restoreCallingIdentity(ident);
7469            }
7470        }
7471    }
7472
7473    @Override
7474    public void resizeStack(int stackBoxId, Rect bounds) {
7475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7476                "resizeStackBox()");
7477        long ident = Binder.clearCallingIdentity();
7478        try {
7479            mWindowManager.resizeStack(stackBoxId, bounds);
7480        } finally {
7481            Binder.restoreCallingIdentity(ident);
7482        }
7483    }
7484
7485    @Override
7486    public List<StackInfo> getAllStackInfos() {
7487        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7488                "getAllStackInfos()");
7489        long ident = Binder.clearCallingIdentity();
7490        try {
7491            synchronized (this) {
7492                return mStackSupervisor.getAllStackInfosLocked();
7493            }
7494        } finally {
7495            Binder.restoreCallingIdentity(ident);
7496        }
7497    }
7498
7499    @Override
7500    public StackInfo getStackInfo(int stackId) {
7501        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7502                "getStackInfo()");
7503        long ident = Binder.clearCallingIdentity();
7504        try {
7505            synchronized (this) {
7506                return mStackSupervisor.getStackInfoLocked(stackId);
7507            }
7508        } finally {
7509            Binder.restoreCallingIdentity(ident);
7510        }
7511    }
7512
7513    @Override
7514    public boolean isInHomeStack(int taskId) {
7515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7516                "getStackInfo()");
7517        long ident = Binder.clearCallingIdentity();
7518        try {
7519            synchronized (this) {
7520                TaskRecord tr = recentTaskForIdLocked(taskId);
7521                if (tr != null) {
7522                    return tr.stack.isHomeStack();
7523                }
7524            }
7525        } finally {
7526            Binder.restoreCallingIdentity(ident);
7527        }
7528        return false;
7529    }
7530
7531    @Override
7532    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7533        synchronized(this) {
7534            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7535        }
7536    }
7537
7538    private boolean isLockTaskAuthorized(ComponentName name) {
7539//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7540//                "startLockTaskMode()");
7541//        DevicePolicyManager dpm = (DevicePolicyManager)
7542//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7543//        return dpm != null && dpm.isLockTaskPermitted(name);
7544        return true;
7545    }
7546
7547    private void startLockTaskMode(TaskRecord task) {
7548        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7549            return;
7550        }
7551        long ident = Binder.clearCallingIdentity();
7552        try {
7553            synchronized (this) {
7554                // Since we lost lock on task, make sure it is still there.
7555                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7556                if (task != null) {
7557                    mStackSupervisor.setLockTaskModeLocked(task);
7558                }
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(ident);
7562        }
7563    }
7564
7565    @Override
7566    public void startLockTaskMode(int taskId) {
7567        long ident = Binder.clearCallingIdentity();
7568        try {
7569            final TaskRecord task;
7570            synchronized (this) {
7571                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7572            }
7573            if (task != null) {
7574                startLockTaskMode(task);
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(ident);
7578        }
7579    }
7580
7581    @Override
7582    public void startLockTaskMode(IBinder token) {
7583        long ident = Binder.clearCallingIdentity();
7584        try {
7585            final TaskRecord task;
7586            synchronized (this) {
7587                final ActivityRecord r = ActivityRecord.forToken(token);
7588                if (r == null) {
7589                    return;
7590                }
7591                task = r.task;
7592            }
7593            if (task != null) {
7594                startLockTaskMode(task);
7595            }
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public void stopLockTaskMode() {
7603//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7604//                "stopLockTaskMode()");
7605        synchronized (this) {
7606            mStackSupervisor.setLockTaskModeLocked(null);
7607        }
7608    }
7609
7610    @Override
7611    public boolean isInLockTaskMode() {
7612        synchronized (this) {
7613            return mStackSupervisor.isInLockTaskMode();
7614        }
7615    }
7616
7617    // =========================================================
7618    // CONTENT PROVIDERS
7619    // =========================================================
7620
7621    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7622        List<ProviderInfo> providers = null;
7623        try {
7624            providers = AppGlobals.getPackageManager().
7625                queryContentProviders(app.processName, app.uid,
7626                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7627        } catch (RemoteException ex) {
7628        }
7629        if (DEBUG_MU)
7630            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7631        int userId = app.userId;
7632        if (providers != null) {
7633            int N = providers.size();
7634            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7635            for (int i=0; i<N; i++) {
7636                ProviderInfo cpi =
7637                    (ProviderInfo)providers.get(i);
7638                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7639                        cpi.name, cpi.flags);
7640                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7641                    // This is a singleton provider, but a user besides the
7642                    // default user is asking to initialize a process it runs
7643                    // in...  well, no, it doesn't actually run in this process,
7644                    // it runs in the process of the default user.  Get rid of it.
7645                    providers.remove(i);
7646                    N--;
7647                    i--;
7648                    continue;
7649                }
7650
7651                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7652                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7653                if (cpr == null) {
7654                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7655                    mProviderMap.putProviderByClass(comp, cpr);
7656                }
7657                if (DEBUG_MU)
7658                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7659                app.pubProviders.put(cpi.name, cpr);
7660                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7661                    // Don't add this if it is a platform component that is marked
7662                    // to run in multiple processes, because this is actually
7663                    // part of the framework so doesn't make sense to track as a
7664                    // separate apk in the process.
7665                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7666                }
7667                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7668            }
7669        }
7670        return providers;
7671    }
7672
7673    /**
7674     * Check if {@link ProcessRecord} has a possible chance at accessing the
7675     * given {@link ProviderInfo}. Final permission checking is always done
7676     * in {@link ContentProvider}.
7677     */
7678    private final String checkContentProviderPermissionLocked(
7679            ProviderInfo cpi, ProcessRecord r) {
7680        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7681        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7682        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7683                cpi.applicationInfo.uid, cpi.exported)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return null;
7686        }
7687        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7688                cpi.applicationInfo.uid, cpi.exported)
7689                == PackageManager.PERMISSION_GRANTED) {
7690            return null;
7691        }
7692
7693        PathPermission[] pps = cpi.pathPermissions;
7694        if (pps != null) {
7695            int i = pps.length;
7696            while (i > 0) {
7697                i--;
7698                PathPermission pp = pps[i];
7699                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7700                        cpi.applicationInfo.uid, cpi.exported)
7701                        == PackageManager.PERMISSION_GRANTED) {
7702                    return null;
7703                }
7704                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7705                        cpi.applicationInfo.uid, cpi.exported)
7706                        == PackageManager.PERMISSION_GRANTED) {
7707                    return null;
7708                }
7709            }
7710        }
7711
7712        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7713        if (perms != null) {
7714            for (GrantUri uri : perms.keySet()) {
7715                if (uri.uri.getAuthority().equals(cpi.authority)) {
7716                    return null;
7717                }
7718            }
7719        }
7720
7721        String msg;
7722        if (!cpi.exported) {
7723            msg = "Permission Denial: opening provider " + cpi.name
7724                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7725                    + ", uid=" + callingUid + ") that is not exported from uid "
7726                    + cpi.applicationInfo.uid;
7727        } else {
7728            msg = "Permission Denial: opening provider " + cpi.name
7729                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7730                    + ", uid=" + callingUid + ") requires "
7731                    + cpi.readPermission + " or " + cpi.writePermission;
7732        }
7733        Slog.w(TAG, msg);
7734        return msg;
7735    }
7736
7737    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7738            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7739        if (r != null) {
7740            for (int i=0; i<r.conProviders.size(); i++) {
7741                ContentProviderConnection conn = r.conProviders.get(i);
7742                if (conn.provider == cpr) {
7743                    if (DEBUG_PROVIDER) Slog.v(TAG,
7744                            "Adding provider requested by "
7745                            + r.processName + " from process "
7746                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7747                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7748                    if (stable) {
7749                        conn.stableCount++;
7750                        conn.numStableIncs++;
7751                    } else {
7752                        conn.unstableCount++;
7753                        conn.numUnstableIncs++;
7754                    }
7755                    return conn;
7756                }
7757            }
7758            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7759            if (stable) {
7760                conn.stableCount = 1;
7761                conn.numStableIncs = 1;
7762            } else {
7763                conn.unstableCount = 1;
7764                conn.numUnstableIncs = 1;
7765            }
7766            cpr.connections.add(conn);
7767            r.conProviders.add(conn);
7768            return conn;
7769        }
7770        cpr.addExternalProcessHandleLocked(externalProcessToken);
7771        return null;
7772    }
7773
7774    boolean decProviderCountLocked(ContentProviderConnection conn,
7775            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7776        if (conn != null) {
7777            cpr = conn.provider;
7778            if (DEBUG_PROVIDER) Slog.v(TAG,
7779                    "Removing provider requested by "
7780                    + conn.client.processName + " from process "
7781                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7782                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7783            if (stable) {
7784                conn.stableCount--;
7785            } else {
7786                conn.unstableCount--;
7787            }
7788            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7789                cpr.connections.remove(conn);
7790                conn.client.conProviders.remove(conn);
7791                return true;
7792            }
7793            return false;
7794        }
7795        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7796        return false;
7797    }
7798
7799    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7800            String name, IBinder token, boolean stable, int userId) {
7801        ContentProviderRecord cpr;
7802        ContentProviderConnection conn = null;
7803        ProviderInfo cpi = null;
7804
7805        synchronized(this) {
7806            ProcessRecord r = null;
7807            if (caller != null) {
7808                r = getRecordForAppLocked(caller);
7809                if (r == null) {
7810                    throw new SecurityException(
7811                            "Unable to find app for caller " + caller
7812                          + " (pid=" + Binder.getCallingPid()
7813                          + ") when getting content provider " + name);
7814                }
7815            }
7816
7817            // First check if this content provider has been published...
7818            cpr = mProviderMap.getProviderByName(name, userId);
7819            boolean providerRunning = cpr != null;
7820            if (providerRunning) {
7821                cpi = cpr.info;
7822                String msg;
7823                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7824                    throw new SecurityException(msg);
7825                }
7826
7827                if (r != null && cpr.canRunHere(r)) {
7828                    // This provider has been published or is in the process
7829                    // of being published...  but it is also allowed to run
7830                    // in the caller's process, so don't make a connection
7831                    // and just let the caller instantiate its own instance.
7832                    ContentProviderHolder holder = cpr.newHolder(null);
7833                    // don't give caller the provider object, it needs
7834                    // to make its own.
7835                    holder.provider = null;
7836                    return holder;
7837                }
7838
7839                final long origId = Binder.clearCallingIdentity();
7840
7841                // In this case the provider instance already exists, so we can
7842                // return it right away.
7843                conn = incProviderCountLocked(r, cpr, token, stable);
7844                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7845                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7846                        // If this is a perceptible app accessing the provider,
7847                        // make sure to count it as being accessed and thus
7848                        // back up on the LRU list.  This is good because
7849                        // content providers are often expensive to start.
7850                        updateLruProcessLocked(cpr.proc, false, null);
7851                    }
7852                }
7853
7854                if (cpr.proc != null) {
7855                    if (false) {
7856                        if (cpr.name.flattenToShortString().equals(
7857                                "com.android.providers.calendar/.CalendarProvider2")) {
7858                            Slog.v(TAG, "****************** KILLING "
7859                                + cpr.name.flattenToShortString());
7860                            Process.killProcess(cpr.proc.pid);
7861                        }
7862                    }
7863                    boolean success = updateOomAdjLocked(cpr.proc);
7864                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7865                    // NOTE: there is still a race here where a signal could be
7866                    // pending on the process even though we managed to update its
7867                    // adj level.  Not sure what to do about this, but at least
7868                    // the race is now smaller.
7869                    if (!success) {
7870                        // Uh oh...  it looks like the provider's process
7871                        // has been killed on us.  We need to wait for a new
7872                        // process to be started, and make sure its death
7873                        // doesn't kill our process.
7874                        Slog.i(TAG,
7875                                "Existing provider " + cpr.name.flattenToShortString()
7876                                + " is crashing; detaching " + r);
7877                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7878                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7879                        if (!lastRef) {
7880                            // This wasn't the last ref our process had on
7881                            // the provider...  we have now been killed, bail.
7882                            return null;
7883                        }
7884                        providerRunning = false;
7885                        conn = null;
7886                    }
7887                }
7888
7889                Binder.restoreCallingIdentity(origId);
7890            }
7891
7892            boolean singleton;
7893            if (!providerRunning) {
7894                try {
7895                    cpi = AppGlobals.getPackageManager().
7896                        resolveContentProvider(name,
7897                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7898                } catch (RemoteException ex) {
7899                }
7900                if (cpi == null) {
7901                    return null;
7902                }
7903                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7904                        cpi.name, cpi.flags);
7905                if (singleton) {
7906                    userId = 0;
7907                }
7908                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7909
7910                String msg;
7911                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7912                    throw new SecurityException(msg);
7913                }
7914
7915                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7916                        && !cpi.processName.equals("system")) {
7917                    // If this content provider does not run in the system
7918                    // process, and the system is not yet ready to run other
7919                    // processes, then fail fast instead of hanging.
7920                    throw new IllegalArgumentException(
7921                            "Attempt to launch content provider before system ready");
7922                }
7923
7924                // Make sure that the user who owns this provider is started.  If not,
7925                // we don't want to allow it to run.
7926                if (mStartedUsers.get(userId) == null) {
7927                    Slog.w(TAG, "Unable to launch app "
7928                            + cpi.applicationInfo.packageName + "/"
7929                            + cpi.applicationInfo.uid + " for provider "
7930                            + name + ": user " + userId + " is stopped");
7931                    return null;
7932                }
7933
7934                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7935                cpr = mProviderMap.getProviderByClass(comp, userId);
7936                final boolean firstClass = cpr == null;
7937                if (firstClass) {
7938                    try {
7939                        ApplicationInfo ai =
7940                            AppGlobals.getPackageManager().
7941                                getApplicationInfo(
7942                                        cpi.applicationInfo.packageName,
7943                                        STOCK_PM_FLAGS, userId);
7944                        if (ai == null) {
7945                            Slog.w(TAG, "No package info for content provider "
7946                                    + cpi.name);
7947                            return null;
7948                        }
7949                        ai = getAppInfoForUser(ai, userId);
7950                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7951                    } catch (RemoteException ex) {
7952                        // pm is in same process, this will never happen.
7953                    }
7954                }
7955
7956                if (r != null && cpr.canRunHere(r)) {
7957                    // If this is a multiprocess provider, then just return its
7958                    // info and allow the caller to instantiate it.  Only do
7959                    // this if the provider is the same user as the caller's
7960                    // process, or can run as root (so can be in any process).
7961                    return cpr.newHolder(null);
7962                }
7963
7964                if (DEBUG_PROVIDER) {
7965                    RuntimeException e = new RuntimeException("here");
7966                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7967                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7968                }
7969
7970                // This is single process, and our app is now connecting to it.
7971                // See if we are already in the process of launching this
7972                // provider.
7973                final int N = mLaunchingProviders.size();
7974                int i;
7975                for (i=0; i<N; i++) {
7976                    if (mLaunchingProviders.get(i) == cpr) {
7977                        break;
7978                    }
7979                }
7980
7981                // If the provider is not already being launched, then get it
7982                // started.
7983                if (i >= N) {
7984                    final long origId = Binder.clearCallingIdentity();
7985
7986                    try {
7987                        // Content provider is now in use, its package can't be stopped.
7988                        try {
7989                            AppGlobals.getPackageManager().setPackageStoppedState(
7990                                    cpr.appInfo.packageName, false, userId);
7991                        } catch (RemoteException e) {
7992                        } catch (IllegalArgumentException e) {
7993                            Slog.w(TAG, "Failed trying to unstop package "
7994                                    + cpr.appInfo.packageName + ": " + e);
7995                        }
7996
7997                        // Use existing process if already started
7998                        ProcessRecord proc = getProcessRecordLocked(
7999                                cpi.processName, cpr.appInfo.uid, false);
8000                        if (proc != null && proc.thread != null) {
8001                            if (DEBUG_PROVIDER) {
8002                                Slog.d(TAG, "Installing in existing process " + proc);
8003                            }
8004                            proc.pubProviders.put(cpi.name, cpr);
8005                            try {
8006                                proc.thread.scheduleInstallProvider(cpi);
8007                            } catch (RemoteException e) {
8008                            }
8009                        } else {
8010                            proc = startProcessLocked(cpi.processName,
8011                                    cpr.appInfo, false, 0, "content provider",
8012                                    new ComponentName(cpi.applicationInfo.packageName,
8013                                            cpi.name), false, false, false);
8014                            if (proc == null) {
8015                                Slog.w(TAG, "Unable to launch app "
8016                                        + cpi.applicationInfo.packageName + "/"
8017                                        + cpi.applicationInfo.uid + " for provider "
8018                                        + name + ": process is bad");
8019                                return null;
8020                            }
8021                        }
8022                        cpr.launchingApp = proc;
8023                        mLaunchingProviders.add(cpr);
8024                    } finally {
8025                        Binder.restoreCallingIdentity(origId);
8026                    }
8027                }
8028
8029                // Make sure the provider is published (the same provider class
8030                // may be published under multiple names).
8031                if (firstClass) {
8032                    mProviderMap.putProviderByClass(comp, cpr);
8033                }
8034
8035                mProviderMap.putProviderByName(name, cpr);
8036                conn = incProviderCountLocked(r, cpr, token, stable);
8037                if (conn != null) {
8038                    conn.waiting = true;
8039                }
8040            }
8041        }
8042
8043        // Wait for the provider to be published...
8044        synchronized (cpr) {
8045            while (cpr.provider == null) {
8046                if (cpr.launchingApp == null) {
8047                    Slog.w(TAG, "Unable to launch app "
8048                            + cpi.applicationInfo.packageName + "/"
8049                            + cpi.applicationInfo.uid + " for provider "
8050                            + name + ": launching app became null");
8051                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8052                            UserHandle.getUserId(cpi.applicationInfo.uid),
8053                            cpi.applicationInfo.packageName,
8054                            cpi.applicationInfo.uid, name);
8055                    return null;
8056                }
8057                try {
8058                    if (DEBUG_MU) {
8059                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8060                                + cpr.launchingApp);
8061                    }
8062                    if (conn != null) {
8063                        conn.waiting = true;
8064                    }
8065                    cpr.wait();
8066                } catch (InterruptedException ex) {
8067                } finally {
8068                    if (conn != null) {
8069                        conn.waiting = false;
8070                    }
8071                }
8072            }
8073        }
8074        return cpr != null ? cpr.newHolder(conn) : null;
8075    }
8076
8077    public final ContentProviderHolder getContentProvider(
8078            IApplicationThread caller, String name, int userId, boolean stable) {
8079        enforceNotIsolatedCaller("getContentProvider");
8080        if (caller == null) {
8081            String msg = "null IApplicationThread when getting content provider "
8082                    + name;
8083            Slog.w(TAG, msg);
8084            throw new SecurityException(msg);
8085        }
8086
8087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8088                false, true, "getContentProvider", null);
8089        return getContentProviderImpl(caller, name, null, stable, userId);
8090    }
8091
8092    public ContentProviderHolder getContentProviderExternal(
8093            String name, int userId, IBinder token) {
8094        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8095            "Do not have permission in call getContentProviderExternal()");
8096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8097                false, true, "getContentProvider", null);
8098        return getContentProviderExternalUnchecked(name, token, userId);
8099    }
8100
8101    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8102            IBinder token, int userId) {
8103        return getContentProviderImpl(null, name, token, true, userId);
8104    }
8105
8106    /**
8107     * Drop a content provider from a ProcessRecord's bookkeeping
8108     */
8109    public void removeContentProvider(IBinder connection, boolean stable) {
8110        enforceNotIsolatedCaller("removeContentProvider");
8111        long ident = Binder.clearCallingIdentity();
8112        try {
8113            synchronized (this) {
8114                ContentProviderConnection conn;
8115                try {
8116                    conn = (ContentProviderConnection)connection;
8117                } catch (ClassCastException e) {
8118                    String msg ="removeContentProvider: " + connection
8119                            + " not a ContentProviderConnection";
8120                    Slog.w(TAG, msg);
8121                    throw new IllegalArgumentException(msg);
8122                }
8123                if (conn == null) {
8124                    throw new NullPointerException("connection is null");
8125                }
8126                if (decProviderCountLocked(conn, null, null, stable)) {
8127                    updateOomAdjLocked();
8128                }
8129            }
8130        } finally {
8131            Binder.restoreCallingIdentity(ident);
8132        }
8133    }
8134
8135    public void removeContentProviderExternal(String name, IBinder token) {
8136        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8137            "Do not have permission in call removeContentProviderExternal()");
8138        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8139    }
8140
8141    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8142        synchronized (this) {
8143            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8144            if(cpr == null) {
8145                //remove from mProvidersByClass
8146                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8147                return;
8148            }
8149
8150            //update content provider record entry info
8151            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8152            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8153            if (localCpr.hasExternalProcessHandles()) {
8154                if (localCpr.removeExternalProcessHandleLocked(token)) {
8155                    updateOomAdjLocked();
8156                } else {
8157                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8158                            + " with no external reference for token: "
8159                            + token + ".");
8160                }
8161            } else {
8162                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8163                        + " with no external references.");
8164            }
8165        }
8166    }
8167
8168    public final void publishContentProviders(IApplicationThread caller,
8169            List<ContentProviderHolder> providers) {
8170        if (providers == null) {
8171            return;
8172        }
8173
8174        enforceNotIsolatedCaller("publishContentProviders");
8175        synchronized (this) {
8176            final ProcessRecord r = getRecordForAppLocked(caller);
8177            if (DEBUG_MU)
8178                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8179            if (r == null) {
8180                throw new SecurityException(
8181                        "Unable to find app for caller " + caller
8182                      + " (pid=" + Binder.getCallingPid()
8183                      + ") when publishing content providers");
8184            }
8185
8186            final long origId = Binder.clearCallingIdentity();
8187
8188            final int N = providers.size();
8189            for (int i=0; i<N; i++) {
8190                ContentProviderHolder src = providers.get(i);
8191                if (src == null || src.info == null || src.provider == null) {
8192                    continue;
8193                }
8194                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8195                if (DEBUG_MU)
8196                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8197                if (dst != null) {
8198                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8199                    mProviderMap.putProviderByClass(comp, dst);
8200                    String names[] = dst.info.authority.split(";");
8201                    for (int j = 0; j < names.length; j++) {
8202                        mProviderMap.putProviderByName(names[j], dst);
8203                    }
8204
8205                    int NL = mLaunchingProviders.size();
8206                    int j;
8207                    for (j=0; j<NL; j++) {
8208                        if (mLaunchingProviders.get(j) == dst) {
8209                            mLaunchingProviders.remove(j);
8210                            j--;
8211                            NL--;
8212                        }
8213                    }
8214                    synchronized (dst) {
8215                        dst.provider = src.provider;
8216                        dst.proc = r;
8217                        dst.notifyAll();
8218                    }
8219                    updateOomAdjLocked(r);
8220                }
8221            }
8222
8223            Binder.restoreCallingIdentity(origId);
8224        }
8225    }
8226
8227    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8228        ContentProviderConnection conn;
8229        try {
8230            conn = (ContentProviderConnection)connection;
8231        } catch (ClassCastException e) {
8232            String msg ="refContentProvider: " + connection
8233                    + " not a ContentProviderConnection";
8234            Slog.w(TAG, msg);
8235            throw new IllegalArgumentException(msg);
8236        }
8237        if (conn == null) {
8238            throw new NullPointerException("connection is null");
8239        }
8240
8241        synchronized (this) {
8242            if (stable > 0) {
8243                conn.numStableIncs += stable;
8244            }
8245            stable = conn.stableCount + stable;
8246            if (stable < 0) {
8247                throw new IllegalStateException("stableCount < 0: " + stable);
8248            }
8249
8250            if (unstable > 0) {
8251                conn.numUnstableIncs += unstable;
8252            }
8253            unstable = conn.unstableCount + unstable;
8254            if (unstable < 0) {
8255                throw new IllegalStateException("unstableCount < 0: " + unstable);
8256            }
8257
8258            if ((stable+unstable) <= 0) {
8259                throw new IllegalStateException("ref counts can't go to zero here: stable="
8260                        + stable + " unstable=" + unstable);
8261            }
8262            conn.stableCount = stable;
8263            conn.unstableCount = unstable;
8264            return !conn.dead;
8265        }
8266    }
8267
8268    public void unstableProviderDied(IBinder connection) {
8269        ContentProviderConnection conn;
8270        try {
8271            conn = (ContentProviderConnection)connection;
8272        } catch (ClassCastException e) {
8273            String msg ="refContentProvider: " + connection
8274                    + " not a ContentProviderConnection";
8275            Slog.w(TAG, msg);
8276            throw new IllegalArgumentException(msg);
8277        }
8278        if (conn == null) {
8279            throw new NullPointerException("connection is null");
8280        }
8281
8282        // Safely retrieve the content provider associated with the connection.
8283        IContentProvider provider;
8284        synchronized (this) {
8285            provider = conn.provider.provider;
8286        }
8287
8288        if (provider == null) {
8289            // Um, yeah, we're way ahead of you.
8290            return;
8291        }
8292
8293        // Make sure the caller is being honest with us.
8294        if (provider.asBinder().pingBinder()) {
8295            // Er, no, still looks good to us.
8296            synchronized (this) {
8297                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8298                        + " says " + conn + " died, but we don't agree");
8299                return;
8300            }
8301        }
8302
8303        // Well look at that!  It's dead!
8304        synchronized (this) {
8305            if (conn.provider.provider != provider) {
8306                // But something changed...  good enough.
8307                return;
8308            }
8309
8310            ProcessRecord proc = conn.provider.proc;
8311            if (proc == null || proc.thread == null) {
8312                // Seems like the process is already cleaned up.
8313                return;
8314            }
8315
8316            // As far as we're concerned, this is just like receiving a
8317            // death notification...  just a bit prematurely.
8318            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8319                    + ") early provider death");
8320            final long ident = Binder.clearCallingIdentity();
8321            try {
8322                appDiedLocked(proc, proc.pid, proc.thread);
8323            } finally {
8324                Binder.restoreCallingIdentity(ident);
8325            }
8326        }
8327    }
8328
8329    @Override
8330    public void appNotRespondingViaProvider(IBinder connection) {
8331        enforceCallingPermission(
8332                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8333
8334        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8335        if (conn == null) {
8336            Slog.w(TAG, "ContentProviderConnection is null");
8337            return;
8338        }
8339
8340        final ProcessRecord host = conn.provider.proc;
8341        if (host == null) {
8342            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8343            return;
8344        }
8345
8346        final long token = Binder.clearCallingIdentity();
8347        try {
8348            appNotResponding(host, null, null, false, "ContentProvider not responding");
8349        } finally {
8350            Binder.restoreCallingIdentity(token);
8351        }
8352    }
8353
8354    public final void installSystemProviders() {
8355        List<ProviderInfo> providers;
8356        synchronized (this) {
8357            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8358            providers = generateApplicationProvidersLocked(app);
8359            if (providers != null) {
8360                for (int i=providers.size()-1; i>=0; i--) {
8361                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8362                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8363                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8364                                + ": not system .apk");
8365                        providers.remove(i);
8366                    }
8367                }
8368            }
8369        }
8370        if (providers != null) {
8371            mSystemThread.installSystemProviders(providers);
8372        }
8373
8374        mCoreSettingsObserver = new CoreSettingsObserver(this);
8375
8376        mUsageStatsService.monitorPackages();
8377    }
8378
8379    /**
8380     * Allows app to retrieve the MIME type of a URI without having permission
8381     * to access its content provider.
8382     *
8383     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8384     *
8385     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8386     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8387     */
8388    public String getProviderMimeType(Uri uri, int userId) {
8389        enforceNotIsolatedCaller("getProviderMimeType");
8390        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8391                userId, false, true, "getProviderMimeType", null);
8392        final String name = uri.getAuthority();
8393        final long ident = Binder.clearCallingIdentity();
8394        ContentProviderHolder holder = null;
8395
8396        try {
8397            holder = getContentProviderExternalUnchecked(name, null, userId);
8398            if (holder != null) {
8399                return holder.provider.getType(uri);
8400            }
8401        } catch (RemoteException e) {
8402            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8403            return null;
8404        } finally {
8405            if (holder != null) {
8406                removeContentProviderExternalUnchecked(name, null, userId);
8407            }
8408            Binder.restoreCallingIdentity(ident);
8409        }
8410
8411        return null;
8412    }
8413
8414    // =========================================================
8415    // GLOBAL MANAGEMENT
8416    // =========================================================
8417
8418    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8419            boolean isolated) {
8420        String proc = customProcess != null ? customProcess : info.processName;
8421        BatteryStatsImpl.Uid.Proc ps = null;
8422        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8423        int uid = info.uid;
8424        if (isolated) {
8425            int userId = UserHandle.getUserId(uid);
8426            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8427            while (true) {
8428                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8429                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8430                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8431                }
8432                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8433                mNextIsolatedProcessUid++;
8434                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8435                    // No process for this uid, use it.
8436                    break;
8437                }
8438                stepsLeft--;
8439                if (stepsLeft <= 0) {
8440                    return null;
8441                }
8442            }
8443        }
8444        return new ProcessRecord(stats, info, proc, uid);
8445    }
8446
8447    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8448        ProcessRecord app;
8449        if (!isolated) {
8450            app = getProcessRecordLocked(info.processName, info.uid, true);
8451        } else {
8452            app = null;
8453        }
8454
8455        if (app == null) {
8456            app = newProcessRecordLocked(info, null, isolated);
8457            mProcessNames.put(info.processName, app.uid, app);
8458            if (isolated) {
8459                mIsolatedProcesses.put(app.uid, app);
8460            }
8461            updateLruProcessLocked(app, false, null);
8462            updateOomAdjLocked();
8463        }
8464
8465        // This package really, really can not be stopped.
8466        try {
8467            AppGlobals.getPackageManager().setPackageStoppedState(
8468                    info.packageName, false, UserHandle.getUserId(app.uid));
8469        } catch (RemoteException e) {
8470        } catch (IllegalArgumentException e) {
8471            Slog.w(TAG, "Failed trying to unstop package "
8472                    + info.packageName + ": " + e);
8473        }
8474
8475        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8476                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8477            app.persistent = true;
8478            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8479        }
8480        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8481            mPersistentStartingProcesses.add(app);
8482            startProcessLocked(app, "added application", app.processName);
8483        }
8484
8485        return app;
8486    }
8487
8488    public void unhandledBack() {
8489        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8490                "unhandledBack()");
8491
8492        synchronized(this) {
8493            final long origId = Binder.clearCallingIdentity();
8494            try {
8495                getFocusedStack().unhandledBackLocked();
8496            } finally {
8497                Binder.restoreCallingIdentity(origId);
8498            }
8499        }
8500    }
8501
8502    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8503        enforceNotIsolatedCaller("openContentUri");
8504        final int userId = UserHandle.getCallingUserId();
8505        String name = uri.getAuthority();
8506        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8507        ParcelFileDescriptor pfd = null;
8508        if (cph != null) {
8509            // We record the binder invoker's uid in thread-local storage before
8510            // going to the content provider to open the file.  Later, in the code
8511            // that handles all permissions checks, we look for this uid and use
8512            // that rather than the Activity Manager's own uid.  The effect is that
8513            // we do the check against the caller's permissions even though it looks
8514            // to the content provider like the Activity Manager itself is making
8515            // the request.
8516            sCallerIdentity.set(new Identity(
8517                    Binder.getCallingPid(), Binder.getCallingUid()));
8518            try {
8519                pfd = cph.provider.openFile(null, uri, "r", null);
8520            } catch (FileNotFoundException e) {
8521                // do nothing; pfd will be returned null
8522            } finally {
8523                // Ensure that whatever happens, we clean up the identity state
8524                sCallerIdentity.remove();
8525            }
8526
8527            // We've got the fd now, so we're done with the provider.
8528            removeContentProviderExternalUnchecked(name, null, userId);
8529        } else {
8530            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8531        }
8532        return pfd;
8533    }
8534
8535    // Actually is sleeping or shutting down or whatever else in the future
8536    // is an inactive state.
8537    public boolean isSleepingOrShuttingDown() {
8538        return mSleeping || mShuttingDown;
8539    }
8540
8541    public boolean isSleeping() {
8542        return mSleeping;
8543    }
8544
8545    void goingToSleep() {
8546        synchronized(this) {
8547            mWentToSleep = true;
8548            updateEventDispatchingLocked();
8549            goToSleepIfNeededLocked();
8550        }
8551    }
8552
8553    void finishRunningVoiceLocked() {
8554        if (mRunningVoice) {
8555            mRunningVoice = false;
8556            goToSleepIfNeededLocked();
8557        }
8558    }
8559
8560    void goToSleepIfNeededLocked() {
8561        if (mWentToSleep && !mRunningVoice) {
8562            if (!mSleeping) {
8563                mSleeping = true;
8564                mStackSupervisor.goingToSleepLocked();
8565
8566                // Initialize the wake times of all processes.
8567                checkExcessivePowerUsageLocked(false);
8568                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8569                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8570                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8571            }
8572        }
8573    }
8574
8575    @Override
8576    public boolean shutdown(int timeout) {
8577        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8578                != PackageManager.PERMISSION_GRANTED) {
8579            throw new SecurityException("Requires permission "
8580                    + android.Manifest.permission.SHUTDOWN);
8581        }
8582
8583        boolean timedout = false;
8584
8585        synchronized(this) {
8586            mShuttingDown = true;
8587            updateEventDispatchingLocked();
8588            timedout = mStackSupervisor.shutdownLocked(timeout);
8589        }
8590
8591        mAppOpsService.shutdown();
8592        mUsageStatsService.shutdown();
8593        mBatteryStatsService.shutdown();
8594        synchronized (this) {
8595            mProcessStats.shutdownLocked();
8596        }
8597
8598        return timedout;
8599    }
8600
8601    public final void activitySlept(IBinder token) {
8602        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8603
8604        final long origId = Binder.clearCallingIdentity();
8605
8606        synchronized (this) {
8607            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8608            if (r != null) {
8609                mStackSupervisor.activitySleptLocked(r);
8610            }
8611        }
8612
8613        Binder.restoreCallingIdentity(origId);
8614    }
8615
8616    void logLockScreen(String msg) {
8617        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8618                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8619                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8620                mStackSupervisor.mDismissKeyguardOnNextActivity);
8621    }
8622
8623    private void comeOutOfSleepIfNeededLocked() {
8624        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8625            if (mSleeping) {
8626                mSleeping = false;
8627                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8628            }
8629        }
8630    }
8631
8632    void wakingUp() {
8633        synchronized(this) {
8634            mWentToSleep = false;
8635            updateEventDispatchingLocked();
8636            comeOutOfSleepIfNeededLocked();
8637        }
8638    }
8639
8640    void startRunningVoiceLocked() {
8641        if (!mRunningVoice) {
8642            mRunningVoice = true;
8643            comeOutOfSleepIfNeededLocked();
8644        }
8645    }
8646
8647    private void updateEventDispatchingLocked() {
8648        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8649    }
8650
8651    public void setLockScreenShown(boolean shown) {
8652        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8653                != PackageManager.PERMISSION_GRANTED) {
8654            throw new SecurityException("Requires permission "
8655                    + android.Manifest.permission.DEVICE_POWER);
8656        }
8657
8658        synchronized(this) {
8659            long ident = Binder.clearCallingIdentity();
8660            try {
8661                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8662                mLockScreenShown = shown;
8663                comeOutOfSleepIfNeededLocked();
8664            } finally {
8665                Binder.restoreCallingIdentity(ident);
8666            }
8667        }
8668    }
8669
8670    public void stopAppSwitches() {
8671        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8672                != PackageManager.PERMISSION_GRANTED) {
8673            throw new SecurityException("Requires permission "
8674                    + android.Manifest.permission.STOP_APP_SWITCHES);
8675        }
8676
8677        synchronized(this) {
8678            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8679                    + APP_SWITCH_DELAY_TIME;
8680            mDidAppSwitch = false;
8681            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8682            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8683            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8684        }
8685    }
8686
8687    public void resumeAppSwitches() {
8688        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8689                != PackageManager.PERMISSION_GRANTED) {
8690            throw new SecurityException("Requires permission "
8691                    + android.Manifest.permission.STOP_APP_SWITCHES);
8692        }
8693
8694        synchronized(this) {
8695            // Note that we don't execute any pending app switches... we will
8696            // let those wait until either the timeout, or the next start
8697            // activity request.
8698            mAppSwitchesAllowedTime = 0;
8699        }
8700    }
8701
8702    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8703            String name) {
8704        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8705            return true;
8706        }
8707
8708        final int perm = checkComponentPermission(
8709                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8710                callingUid, -1, true);
8711        if (perm == PackageManager.PERMISSION_GRANTED) {
8712            return true;
8713        }
8714
8715        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8716        return false;
8717    }
8718
8719    public void setDebugApp(String packageName, boolean waitForDebugger,
8720            boolean persistent) {
8721        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8722                "setDebugApp()");
8723
8724        long ident = Binder.clearCallingIdentity();
8725        try {
8726            // Note that this is not really thread safe if there are multiple
8727            // callers into it at the same time, but that's not a situation we
8728            // care about.
8729            if (persistent) {
8730                final ContentResolver resolver = mContext.getContentResolver();
8731                Settings.Global.putString(
8732                    resolver, Settings.Global.DEBUG_APP,
8733                    packageName);
8734                Settings.Global.putInt(
8735                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8736                    waitForDebugger ? 1 : 0);
8737            }
8738
8739            synchronized (this) {
8740                if (!persistent) {
8741                    mOrigDebugApp = mDebugApp;
8742                    mOrigWaitForDebugger = mWaitForDebugger;
8743                }
8744                mDebugApp = packageName;
8745                mWaitForDebugger = waitForDebugger;
8746                mDebugTransient = !persistent;
8747                if (packageName != null) {
8748                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8749                            false, UserHandle.USER_ALL, "set debug app");
8750                }
8751            }
8752        } finally {
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755    }
8756
8757    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8758        synchronized (this) {
8759            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8760            if (!isDebuggable) {
8761                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8762                    throw new SecurityException("Process not debuggable: " + app.packageName);
8763                }
8764            }
8765
8766            mOpenGlTraceApp = processName;
8767        }
8768    }
8769
8770    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8771            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8772        synchronized (this) {
8773            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8774            if (!isDebuggable) {
8775                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8776                    throw new SecurityException("Process not debuggable: " + app.packageName);
8777                }
8778            }
8779            mProfileApp = processName;
8780            mProfileFile = profileFile;
8781            if (mProfileFd != null) {
8782                try {
8783                    mProfileFd.close();
8784                } catch (IOException e) {
8785                }
8786                mProfileFd = null;
8787            }
8788            mProfileFd = profileFd;
8789            mProfileType = 0;
8790            mAutoStopProfiler = autoStopProfiler;
8791        }
8792    }
8793
8794    @Override
8795    public void setAlwaysFinish(boolean enabled) {
8796        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8797                "setAlwaysFinish()");
8798
8799        Settings.Global.putInt(
8800                mContext.getContentResolver(),
8801                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8802
8803        synchronized (this) {
8804            mAlwaysFinishActivities = enabled;
8805        }
8806    }
8807
8808    @Override
8809    public void setActivityController(IActivityController controller) {
8810        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8811                "setActivityController()");
8812        synchronized (this) {
8813            mController = controller;
8814            Watchdog.getInstance().setActivityController(controller);
8815        }
8816    }
8817
8818    @Override
8819    public void setUserIsMonkey(boolean userIsMonkey) {
8820        synchronized (this) {
8821            synchronized (mPidsSelfLocked) {
8822                final int callingPid = Binder.getCallingPid();
8823                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8824                if (precessRecord == null) {
8825                    throw new SecurityException("Unknown process: " + callingPid);
8826                }
8827                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8828                    throw new SecurityException("Only an instrumentation process "
8829                            + "with a UiAutomation can call setUserIsMonkey");
8830                }
8831            }
8832            mUserIsMonkey = userIsMonkey;
8833        }
8834    }
8835
8836    @Override
8837    public boolean isUserAMonkey() {
8838        synchronized (this) {
8839            // If there is a controller also implies the user is a monkey.
8840            return (mUserIsMonkey || mController != null);
8841        }
8842    }
8843
8844    public void requestBugReport() {
8845        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8846        SystemProperties.set("ctl.start", "bugreport");
8847    }
8848
8849    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8850        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8851    }
8852
8853    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8854        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8855            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8856        }
8857        return KEY_DISPATCHING_TIMEOUT;
8858    }
8859
8860    @Override
8861    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8862        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8863                != PackageManager.PERMISSION_GRANTED) {
8864            throw new SecurityException("Requires permission "
8865                    + android.Manifest.permission.FILTER_EVENTS);
8866        }
8867        ProcessRecord proc;
8868        long timeout;
8869        synchronized (this) {
8870            synchronized (mPidsSelfLocked) {
8871                proc = mPidsSelfLocked.get(pid);
8872            }
8873            timeout = getInputDispatchingTimeoutLocked(proc);
8874        }
8875
8876        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8877            return -1;
8878        }
8879
8880        return timeout;
8881    }
8882
8883    /**
8884     * Handle input dispatching timeouts.
8885     * Returns whether input dispatching should be aborted or not.
8886     */
8887    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8888            final ActivityRecord activity, final ActivityRecord parent,
8889            final boolean aboveSystem, String reason) {
8890        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.FILTER_EVENTS);
8894        }
8895
8896        final String annotation;
8897        if (reason == null) {
8898            annotation = "Input dispatching timed out";
8899        } else {
8900            annotation = "Input dispatching timed out (" + reason + ")";
8901        }
8902
8903        if (proc != null) {
8904            synchronized (this) {
8905                if (proc.debugging) {
8906                    return false;
8907                }
8908
8909                if (mDidDexOpt) {
8910                    // Give more time since we were dexopting.
8911                    mDidDexOpt = false;
8912                    return false;
8913                }
8914
8915                if (proc.instrumentationClass != null) {
8916                    Bundle info = new Bundle();
8917                    info.putString("shortMsg", "keyDispatchingTimedOut");
8918                    info.putString("longMsg", annotation);
8919                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8920                    return true;
8921                }
8922            }
8923            mHandler.post(new Runnable() {
8924                @Override
8925                public void run() {
8926                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8927                }
8928            });
8929        }
8930
8931        return true;
8932    }
8933
8934    public Bundle getAssistContextExtras(int requestType) {
8935        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8936                "getAssistContextExtras()");
8937        PendingAssistExtras pae;
8938        Bundle extras = new Bundle();
8939        synchronized (this) {
8940            ActivityRecord activity = getFocusedStack().mResumedActivity;
8941            if (activity == null) {
8942                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8943                return null;
8944            }
8945            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8946            if (activity.app == null || activity.app.thread == null) {
8947                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8948                return extras;
8949            }
8950            if (activity.app.pid == Binder.getCallingPid()) {
8951                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8952                return extras;
8953            }
8954            pae = new PendingAssistExtras(activity);
8955            try {
8956                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8957                        requestType);
8958                mPendingAssistExtras.add(pae);
8959                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8960            } catch (RemoteException e) {
8961                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8962                return extras;
8963            }
8964        }
8965        synchronized (pae) {
8966            while (!pae.haveResult) {
8967                try {
8968                    pae.wait();
8969                } catch (InterruptedException e) {
8970                }
8971            }
8972            if (pae.result != null) {
8973                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8974            }
8975        }
8976        synchronized (this) {
8977            mPendingAssistExtras.remove(pae);
8978            mHandler.removeCallbacks(pae);
8979        }
8980        return extras;
8981    }
8982
8983    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8984        PendingAssistExtras pae = (PendingAssistExtras)token;
8985        synchronized (pae) {
8986            pae.result = extras;
8987            pae.haveResult = true;
8988            pae.notifyAll();
8989        }
8990    }
8991
8992    public void registerProcessObserver(IProcessObserver observer) {
8993        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8994                "registerProcessObserver()");
8995        synchronized (this) {
8996            mProcessObservers.register(observer);
8997        }
8998    }
8999
9000    @Override
9001    public void unregisterProcessObserver(IProcessObserver observer) {
9002        synchronized (this) {
9003            mProcessObservers.unregister(observer);
9004        }
9005    }
9006
9007    @Override
9008    public boolean convertFromTranslucent(IBinder token) {
9009        final long origId = Binder.clearCallingIdentity();
9010        try {
9011            synchronized (this) {
9012                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9013                if (r == null) {
9014                    return false;
9015                }
9016                if (r.changeWindowTranslucency(true)) {
9017                    mWindowManager.setAppFullscreen(token, true);
9018                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9019                    return true;
9020                }
9021                return false;
9022            }
9023        } finally {
9024            Binder.restoreCallingIdentity(origId);
9025        }
9026    }
9027
9028    @Override
9029    public boolean convertToTranslucent(IBinder token) {
9030        final long origId = Binder.clearCallingIdentity();
9031        try {
9032            synchronized (this) {
9033                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9034                if (r == null) {
9035                    return false;
9036                }
9037                if (r.changeWindowTranslucency(false)) {
9038                    r.task.stack.convertToTranslucent(r);
9039                    mWindowManager.setAppFullscreen(token, false);
9040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9041                    return true;
9042                }
9043                return false;
9044            }
9045        } finally {
9046            Binder.restoreCallingIdentity(origId);
9047        }
9048    }
9049
9050    @Override
9051    public void setImmersive(IBinder token, boolean immersive) {
9052        synchronized(this) {
9053            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9054            if (r == null) {
9055                throw new IllegalArgumentException();
9056            }
9057            r.immersive = immersive;
9058
9059            // update associated state if we're frontmost
9060            if (r == mFocusedActivity) {
9061                if (DEBUG_IMMERSIVE) {
9062                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9063                }
9064                applyUpdateLockStateLocked(r);
9065            }
9066        }
9067    }
9068
9069    @Override
9070    public boolean isImmersive(IBinder token) {
9071        synchronized (this) {
9072            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9073            if (r == null) {
9074                throw new IllegalArgumentException();
9075            }
9076            return r.immersive;
9077        }
9078    }
9079
9080    public boolean isTopActivityImmersive() {
9081        enforceNotIsolatedCaller("startActivity");
9082        synchronized (this) {
9083            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9084            return (r != null) ? r.immersive : false;
9085        }
9086    }
9087
9088    public final void enterSafeMode() {
9089        synchronized(this) {
9090            // It only makes sense to do this before the system is ready
9091            // and started launching other packages.
9092            if (!mSystemReady) {
9093                try {
9094                    AppGlobals.getPackageManager().enterSafeMode();
9095                } catch (RemoteException e) {
9096                }
9097            }
9098
9099            mSafeMode = true;
9100        }
9101    }
9102
9103    public final void showSafeModeOverlay() {
9104        View v = LayoutInflater.from(mContext).inflate(
9105                com.android.internal.R.layout.safe_mode, null);
9106        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9107        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9108        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9109        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9110        lp.gravity = Gravity.BOTTOM | Gravity.START;
9111        lp.format = v.getBackground().getOpacity();
9112        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9113                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9114        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9115        ((WindowManager)mContext.getSystemService(
9116                Context.WINDOW_SERVICE)).addView(v, lp);
9117    }
9118
9119    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9120        if (!(sender instanceof PendingIntentRecord)) {
9121            return;
9122        }
9123        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9124        synchronized (stats) {
9125            if (mBatteryStatsService.isOnBattery()) {
9126                mBatteryStatsService.enforceCallingPermission();
9127                PendingIntentRecord rec = (PendingIntentRecord)sender;
9128                int MY_UID = Binder.getCallingUid();
9129                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9130                BatteryStatsImpl.Uid.Pkg pkg =
9131                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9132                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9133                pkg.incWakeupsLocked();
9134            }
9135        }
9136    }
9137
9138    public boolean killPids(int[] pids, String pReason, boolean secure) {
9139        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9140            throw new SecurityException("killPids only available to the system");
9141        }
9142        String reason = (pReason == null) ? "Unknown" : pReason;
9143        // XXX Note: don't acquire main activity lock here, because the window
9144        // manager calls in with its locks held.
9145
9146        boolean killed = false;
9147        synchronized (mPidsSelfLocked) {
9148            int[] types = new int[pids.length];
9149            int worstType = 0;
9150            for (int i=0; i<pids.length; i++) {
9151                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9152                if (proc != null) {
9153                    int type = proc.setAdj;
9154                    types[i] = type;
9155                    if (type > worstType) {
9156                        worstType = type;
9157                    }
9158                }
9159            }
9160
9161            // If the worst oom_adj is somewhere in the cached proc LRU range,
9162            // then constrain it so we will kill all cached procs.
9163            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9164                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9165                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9166            }
9167
9168            // If this is not a secure call, don't let it kill processes that
9169            // are important.
9170            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9171                worstType = ProcessList.SERVICE_ADJ;
9172            }
9173
9174            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9175            for (int i=0; i<pids.length; i++) {
9176                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9177                if (proc == null) {
9178                    continue;
9179                }
9180                int adj = proc.setAdj;
9181                if (adj >= worstType && !proc.killedByAm) {
9182                    killUnneededProcessLocked(proc, reason);
9183                    killed = true;
9184                }
9185            }
9186        }
9187        return killed;
9188    }
9189
9190    @Override
9191    public void killUid(int uid, String reason) {
9192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9193            throw new SecurityException("killUid only available to the system");
9194        }
9195        synchronized (this) {
9196            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9197                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9198                    reason != null ? reason : "kill uid");
9199        }
9200    }
9201
9202    @Override
9203    public boolean killProcessesBelowForeground(String reason) {
9204        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9205            throw new SecurityException("killProcessesBelowForeground() only available to system");
9206        }
9207
9208        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9209    }
9210
9211    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9212        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9213            throw new SecurityException("killProcessesBelowAdj() only available to system");
9214        }
9215
9216        boolean killed = false;
9217        synchronized (mPidsSelfLocked) {
9218            final int size = mPidsSelfLocked.size();
9219            for (int i = 0; i < size; i++) {
9220                final int pid = mPidsSelfLocked.keyAt(i);
9221                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9222                if (proc == null) continue;
9223
9224                final int adj = proc.setAdj;
9225                if (adj > belowAdj && !proc.killedByAm) {
9226                    killUnneededProcessLocked(proc, reason);
9227                    killed = true;
9228                }
9229            }
9230        }
9231        return killed;
9232    }
9233
9234    @Override
9235    public void hang(final IBinder who, boolean allowRestart) {
9236        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9237                != PackageManager.PERMISSION_GRANTED) {
9238            throw new SecurityException("Requires permission "
9239                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9240        }
9241
9242        final IBinder.DeathRecipient death = new DeathRecipient() {
9243            @Override
9244            public void binderDied() {
9245                synchronized (this) {
9246                    notifyAll();
9247                }
9248            }
9249        };
9250
9251        try {
9252            who.linkToDeath(death, 0);
9253        } catch (RemoteException e) {
9254            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9255            return;
9256        }
9257
9258        synchronized (this) {
9259            Watchdog.getInstance().setAllowRestart(allowRestart);
9260            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9261            synchronized (death) {
9262                while (who.isBinderAlive()) {
9263                    try {
9264                        death.wait();
9265                    } catch (InterruptedException e) {
9266                    }
9267                }
9268            }
9269            Watchdog.getInstance().setAllowRestart(true);
9270        }
9271    }
9272
9273    @Override
9274    public void restart() {
9275        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9276                != PackageManager.PERMISSION_GRANTED) {
9277            throw new SecurityException("Requires permission "
9278                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9279        }
9280
9281        Log.i(TAG, "Sending shutdown broadcast...");
9282
9283        BroadcastReceiver br = new BroadcastReceiver() {
9284            @Override public void onReceive(Context context, Intent intent) {
9285                // Now the broadcast is done, finish up the low-level shutdown.
9286                Log.i(TAG, "Shutting down activity manager...");
9287                shutdown(10000);
9288                Log.i(TAG, "Shutdown complete, restarting!");
9289                Process.killProcess(Process.myPid());
9290                System.exit(10);
9291            }
9292        };
9293
9294        // First send the high-level shut down broadcast.
9295        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9296        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9297        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9298        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9299        mContext.sendOrderedBroadcastAsUser(intent,
9300                UserHandle.ALL, null, br, mHandler, 0, null, null);
9301        */
9302        br.onReceive(mContext, intent);
9303    }
9304
9305    private long getLowRamTimeSinceIdle(long now) {
9306        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9307    }
9308
9309    @Override
9310    public void performIdleMaintenance() {
9311        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9312                != PackageManager.PERMISSION_GRANTED) {
9313            throw new SecurityException("Requires permission "
9314                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9315        }
9316
9317        synchronized (this) {
9318            final long now = SystemClock.uptimeMillis();
9319            final long timeSinceLastIdle = now - mLastIdleTime;
9320            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9321            mLastIdleTime = now;
9322            mLowRamTimeSinceLastIdle = 0;
9323            if (mLowRamStartTime != 0) {
9324                mLowRamStartTime = now;
9325            }
9326
9327            StringBuilder sb = new StringBuilder(128);
9328            sb.append("Idle maintenance over ");
9329            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9330            sb.append(" low RAM for ");
9331            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9332            Slog.i(TAG, sb.toString());
9333
9334            // If at least 1/3 of our time since the last idle period has been spent
9335            // with RAM low, then we want to kill processes.
9336            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9337
9338            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9339                ProcessRecord proc = mLruProcesses.get(i);
9340                if (proc.notCachedSinceIdle) {
9341                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9342                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9343                        if (doKilling && proc.initialIdlePss != 0
9344                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9345                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9346                                    + " from " + proc.initialIdlePss + ")");
9347                        }
9348                    }
9349                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9350                    proc.notCachedSinceIdle = true;
9351                    proc.initialIdlePss = 0;
9352                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9353                            isSleeping(), now);
9354                }
9355            }
9356
9357            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9358            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9359        }
9360    }
9361
9362    private void retrieveSettings() {
9363        final ContentResolver resolver = mContext.getContentResolver();
9364        String debugApp = Settings.Global.getString(
9365            resolver, Settings.Global.DEBUG_APP);
9366        boolean waitForDebugger = Settings.Global.getInt(
9367            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9368        boolean alwaysFinishActivities = Settings.Global.getInt(
9369            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9370        boolean forceRtl = Settings.Global.getInt(
9371                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9372        // Transfer any global setting for forcing RTL layout, into a System Property
9373        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9374
9375        Configuration configuration = new Configuration();
9376        Settings.System.getConfiguration(resolver, configuration);
9377        if (forceRtl) {
9378            // This will take care of setting the correct layout direction flags
9379            configuration.setLayoutDirection(configuration.locale);
9380        }
9381
9382        synchronized (this) {
9383            mDebugApp = mOrigDebugApp = debugApp;
9384            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9385            mAlwaysFinishActivities = alwaysFinishActivities;
9386            // This happens before any activities are started, so we can
9387            // change mConfiguration in-place.
9388            updateConfigurationLocked(configuration, null, false, true);
9389            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9390        }
9391    }
9392
9393    public boolean testIsSystemReady() {
9394        // no need to synchronize(this) just to read & return the value
9395        return mSystemReady;
9396    }
9397
9398    private static File getCalledPreBootReceiversFile() {
9399        File dataDir = Environment.getDataDirectory();
9400        File systemDir = new File(dataDir, "system");
9401        File fname = new File(systemDir, "called_pre_boots.dat");
9402        return fname;
9403    }
9404
9405    static final int LAST_DONE_VERSION = 10000;
9406
9407    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9408        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9409        File file = getCalledPreBootReceiversFile();
9410        FileInputStream fis = null;
9411        try {
9412            fis = new FileInputStream(file);
9413            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9414            int fvers = dis.readInt();
9415            if (fvers == LAST_DONE_VERSION) {
9416                String vers = dis.readUTF();
9417                String codename = dis.readUTF();
9418                String build = dis.readUTF();
9419                if (android.os.Build.VERSION.RELEASE.equals(vers)
9420                        && android.os.Build.VERSION.CODENAME.equals(codename)
9421                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9422                    int num = dis.readInt();
9423                    while (num > 0) {
9424                        num--;
9425                        String pkg = dis.readUTF();
9426                        String cls = dis.readUTF();
9427                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9428                    }
9429                }
9430            }
9431        } catch (FileNotFoundException e) {
9432        } catch (IOException e) {
9433            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9434        } finally {
9435            if (fis != null) {
9436                try {
9437                    fis.close();
9438                } catch (IOException e) {
9439                }
9440            }
9441        }
9442        return lastDoneReceivers;
9443    }
9444
9445    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9446        File file = getCalledPreBootReceiversFile();
9447        FileOutputStream fos = null;
9448        DataOutputStream dos = null;
9449        try {
9450            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9451            fos = new FileOutputStream(file);
9452            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9453            dos.writeInt(LAST_DONE_VERSION);
9454            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9455            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9456            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9457            dos.writeInt(list.size());
9458            for (int i=0; i<list.size(); i++) {
9459                dos.writeUTF(list.get(i).getPackageName());
9460                dos.writeUTF(list.get(i).getClassName());
9461            }
9462        } catch (IOException e) {
9463            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9464            file.delete();
9465        } finally {
9466            FileUtils.sync(fos);
9467            if (dos != null) {
9468                try {
9469                    dos.close();
9470                } catch (IOException e) {
9471                    // TODO Auto-generated catch block
9472                    e.printStackTrace();
9473                }
9474            }
9475        }
9476    }
9477
9478    public void systemReady(final Runnable goingCallback) {
9479        synchronized(this) {
9480            if (mSystemReady) {
9481                if (goingCallback != null) goingCallback.run();
9482                return;
9483            }
9484
9485            // Check to see if there are any update receivers to run.
9486            if (!mDidUpdate) {
9487                if (mWaitingUpdate) {
9488                    return;
9489                }
9490                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9491                List<ResolveInfo> ris = null;
9492                try {
9493                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9494                            intent, null, 0, 0);
9495                } catch (RemoteException e) {
9496                }
9497                if (ris != null) {
9498                    for (int i=ris.size()-1; i>=0; i--) {
9499                        if ((ris.get(i).activityInfo.applicationInfo.flags
9500                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9501                            ris.remove(i);
9502                        }
9503                    }
9504                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9505
9506                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9507
9508                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9509                    for (int i=0; i<ris.size(); i++) {
9510                        ActivityInfo ai = ris.get(i).activityInfo;
9511                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9512                        if (lastDoneReceivers.contains(comp)) {
9513                            // We already did the pre boot receiver for this app with the current
9514                            // platform version, so don't do it again...
9515                            ris.remove(i);
9516                            i--;
9517                            // ...however, do keep it as one that has been done, so we don't
9518                            // forget about it when rewriting the file of last done receivers.
9519                            doneReceivers.add(comp);
9520                        }
9521                    }
9522
9523                    final int[] users = getUsersLocked();
9524                    for (int i=0; i<ris.size(); i++) {
9525                        ActivityInfo ai = ris.get(i).activityInfo;
9526                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9527                        doneReceivers.add(comp);
9528                        intent.setComponent(comp);
9529                        for (int j=0; j<users.length; j++) {
9530                            IIntentReceiver finisher = null;
9531                            if (i == ris.size()-1 && j == users.length-1) {
9532                                finisher = new IIntentReceiver.Stub() {
9533                                    public void performReceive(Intent intent, int resultCode,
9534                                            String data, Bundle extras, boolean ordered,
9535                                            boolean sticky, int sendingUser) {
9536                                        // The raw IIntentReceiver interface is called
9537                                        // with the AM lock held, so redispatch to
9538                                        // execute our code without the lock.
9539                                        mHandler.post(new Runnable() {
9540                                            public void run() {
9541                                                synchronized (ActivityManagerService.this) {
9542                                                    mDidUpdate = true;
9543                                                }
9544                                                writeLastDonePreBootReceivers(doneReceivers);
9545                                                showBootMessage(mContext.getText(
9546                                                        R.string.android_upgrading_complete),
9547                                                        false);
9548                                                systemReady(goingCallback);
9549                                            }
9550                                        });
9551                                    }
9552                                };
9553                            }
9554                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9555                                    + " for user " + users[j]);
9556                            broadcastIntentLocked(null, null, intent, null, finisher,
9557                                    0, null, null, null, AppOpsManager.OP_NONE,
9558                                    true, false, MY_PID, Process.SYSTEM_UID,
9559                                    users[j]);
9560                            if (finisher != null) {
9561                                mWaitingUpdate = true;
9562                            }
9563                        }
9564                    }
9565                }
9566                if (mWaitingUpdate) {
9567                    return;
9568                }
9569                mDidUpdate = true;
9570            }
9571
9572            mAppOpsService.systemReady();
9573            mSystemReady = true;
9574        }
9575
9576        ArrayList<ProcessRecord> procsToKill = null;
9577        synchronized(mPidsSelfLocked) {
9578            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9579                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9580                if (!isAllowedWhileBooting(proc.info)){
9581                    if (procsToKill == null) {
9582                        procsToKill = new ArrayList<ProcessRecord>();
9583                    }
9584                    procsToKill.add(proc);
9585                }
9586            }
9587        }
9588
9589        synchronized(this) {
9590            if (procsToKill != null) {
9591                for (int i=procsToKill.size()-1; i>=0; i--) {
9592                    ProcessRecord proc = procsToKill.get(i);
9593                    Slog.i(TAG, "Removing system update proc: " + proc);
9594                    removeProcessLocked(proc, true, false, "system update done");
9595                }
9596            }
9597
9598            // Now that we have cleaned up any update processes, we
9599            // are ready to start launching real processes and know that
9600            // we won't trample on them any more.
9601            mProcessesReady = true;
9602        }
9603
9604        Slog.i(TAG, "System now ready");
9605        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9606            SystemClock.uptimeMillis());
9607
9608        synchronized(this) {
9609            // Make sure we have no pre-ready processes sitting around.
9610
9611            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9612                ResolveInfo ri = mContext.getPackageManager()
9613                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9614                                STOCK_PM_FLAGS);
9615                CharSequence errorMsg = null;
9616                if (ri != null) {
9617                    ActivityInfo ai = ri.activityInfo;
9618                    ApplicationInfo app = ai.applicationInfo;
9619                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9620                        mTopAction = Intent.ACTION_FACTORY_TEST;
9621                        mTopData = null;
9622                        mTopComponent = new ComponentName(app.packageName,
9623                                ai.name);
9624                    } else {
9625                        errorMsg = mContext.getResources().getText(
9626                                com.android.internal.R.string.factorytest_not_system);
9627                    }
9628                } else {
9629                    errorMsg = mContext.getResources().getText(
9630                            com.android.internal.R.string.factorytest_no_action);
9631                }
9632                if (errorMsg != null) {
9633                    mTopAction = null;
9634                    mTopData = null;
9635                    mTopComponent = null;
9636                    Message msg = Message.obtain();
9637                    msg.what = SHOW_FACTORY_ERROR_MSG;
9638                    msg.getData().putCharSequence("msg", errorMsg);
9639                    mHandler.sendMessage(msg);
9640                }
9641            }
9642        }
9643
9644        retrieveSettings();
9645
9646        synchronized (this) {
9647            readGrantedUriPermissionsLocked();
9648        }
9649
9650        if (goingCallback != null) goingCallback.run();
9651
9652        mSystemServiceManager.startUser(mCurrentUserId);
9653
9654        synchronized (this) {
9655            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9656                try {
9657                    List apps = AppGlobals.getPackageManager().
9658                        getPersistentApplications(STOCK_PM_FLAGS);
9659                    if (apps != null) {
9660                        int N = apps.size();
9661                        int i;
9662                        for (i=0; i<N; i++) {
9663                            ApplicationInfo info
9664                                = (ApplicationInfo)apps.get(i);
9665                            if (info != null &&
9666                                    !info.packageName.equals("android")) {
9667                                addAppLocked(info, false);
9668                            }
9669                        }
9670                    }
9671                } catch (RemoteException ex) {
9672                    // pm is in same process, this will never happen.
9673                }
9674            }
9675
9676            // Start up initial activity.
9677            mBooting = true;
9678
9679            try {
9680                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9681                    Message msg = Message.obtain();
9682                    msg.what = SHOW_UID_ERROR_MSG;
9683                    mHandler.sendMessage(msg);
9684                }
9685            } catch (RemoteException e) {
9686            }
9687
9688            long ident = Binder.clearCallingIdentity();
9689            try {
9690                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9691                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9692                        | Intent.FLAG_RECEIVER_FOREGROUND);
9693                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9694                broadcastIntentLocked(null, null, intent,
9695                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9696                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9697                intent = new Intent(Intent.ACTION_USER_STARTING);
9698                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9699                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9700                broadcastIntentLocked(null, null, intent,
9701                        null, new IIntentReceiver.Stub() {
9702                            @Override
9703                            public void performReceive(Intent intent, int resultCode, String data,
9704                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9705                                    throws RemoteException {
9706                            }
9707                        }, 0, null, null,
9708                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9709                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9710            } catch (Throwable t) {
9711                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9712            } finally {
9713                Binder.restoreCallingIdentity(ident);
9714            }
9715            mStackSupervisor.resumeTopActivitiesLocked();
9716            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9717        }
9718    }
9719
9720    private boolean makeAppCrashingLocked(ProcessRecord app,
9721            String shortMsg, String longMsg, String stackTrace) {
9722        app.crashing = true;
9723        app.crashingReport = generateProcessError(app,
9724                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9725        startAppProblemLocked(app);
9726        app.stopFreezingAllLocked();
9727        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9728    }
9729
9730    private void makeAppNotRespondingLocked(ProcessRecord app,
9731            String activity, String shortMsg, String longMsg) {
9732        app.notResponding = true;
9733        app.notRespondingReport = generateProcessError(app,
9734                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9735                activity, shortMsg, longMsg, null);
9736        startAppProblemLocked(app);
9737        app.stopFreezingAllLocked();
9738    }
9739
9740    /**
9741     * Generate a process error record, suitable for attachment to a ProcessRecord.
9742     *
9743     * @param app The ProcessRecord in which the error occurred.
9744     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9745     *                      ActivityManager.AppErrorStateInfo
9746     * @param activity The activity associated with the crash, if known.
9747     * @param shortMsg Short message describing the crash.
9748     * @param longMsg Long message describing the crash.
9749     * @param stackTrace Full crash stack trace, may be null.
9750     *
9751     * @return Returns a fully-formed AppErrorStateInfo record.
9752     */
9753    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9754            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9755        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9756
9757        report.condition = condition;
9758        report.processName = app.processName;
9759        report.pid = app.pid;
9760        report.uid = app.info.uid;
9761        report.tag = activity;
9762        report.shortMsg = shortMsg;
9763        report.longMsg = longMsg;
9764        report.stackTrace = stackTrace;
9765
9766        return report;
9767    }
9768
9769    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9770        synchronized (this) {
9771            app.crashing = false;
9772            app.crashingReport = null;
9773            app.notResponding = false;
9774            app.notRespondingReport = null;
9775            if (app.anrDialog == fromDialog) {
9776                app.anrDialog = null;
9777            }
9778            if (app.waitDialog == fromDialog) {
9779                app.waitDialog = null;
9780            }
9781            if (app.pid > 0 && app.pid != MY_PID) {
9782                handleAppCrashLocked(app, null, null, null);
9783                killUnneededProcessLocked(app, "user request after error");
9784            }
9785        }
9786    }
9787
9788    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9789            String stackTrace) {
9790        long now = SystemClock.uptimeMillis();
9791
9792        Long crashTime;
9793        if (!app.isolated) {
9794            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9795        } else {
9796            crashTime = null;
9797        }
9798        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9799            // This process loses!
9800            Slog.w(TAG, "Process " + app.info.processName
9801                    + " has crashed too many times: killing!");
9802            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9803                    app.userId, app.info.processName, app.uid);
9804            mStackSupervisor.handleAppCrashLocked(app);
9805            if (!app.persistent) {
9806                // We don't want to start this process again until the user
9807                // explicitly does so...  but for persistent process, we really
9808                // need to keep it running.  If a persistent process is actually
9809                // repeatedly crashing, then badness for everyone.
9810                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9811                        app.info.processName);
9812                if (!app.isolated) {
9813                    // XXX We don't have a way to mark isolated processes
9814                    // as bad, since they don't have a peristent identity.
9815                    mBadProcesses.put(app.info.processName, app.uid,
9816                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9817                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9818                }
9819                app.bad = true;
9820                app.removed = true;
9821                // Don't let services in this process be restarted and potentially
9822                // annoy the user repeatedly.  Unless it is persistent, since those
9823                // processes run critical code.
9824                removeProcessLocked(app, false, false, "crash");
9825                mStackSupervisor.resumeTopActivitiesLocked();
9826                return false;
9827            }
9828            mStackSupervisor.resumeTopActivitiesLocked();
9829        } else {
9830            mStackSupervisor.finishTopRunningActivityLocked(app);
9831        }
9832
9833        // Bump up the crash count of any services currently running in the proc.
9834        for (int i=app.services.size()-1; i>=0; i--) {
9835            // Any services running in the application need to be placed
9836            // back in the pending list.
9837            ServiceRecord sr = app.services.valueAt(i);
9838            sr.crashCount++;
9839        }
9840
9841        // If the crashing process is what we consider to be the "home process" and it has been
9842        // replaced by a third-party app, clear the package preferred activities from packages
9843        // with a home activity running in the process to prevent a repeatedly crashing app
9844        // from blocking the user to manually clear the list.
9845        final ArrayList<ActivityRecord> activities = app.activities;
9846        if (app == mHomeProcess && activities.size() > 0
9847                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9848            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9849                final ActivityRecord r = activities.get(activityNdx);
9850                if (r.isHomeActivity()) {
9851                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9852                    try {
9853                        ActivityThread.getPackageManager()
9854                                .clearPackagePreferredActivities(r.packageName);
9855                    } catch (RemoteException c) {
9856                        // pm is in same process, this will never happen.
9857                    }
9858                }
9859            }
9860        }
9861
9862        if (!app.isolated) {
9863            // XXX Can't keep track of crash times for isolated processes,
9864            // because they don't have a perisistent identity.
9865            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9866        }
9867
9868        return true;
9869    }
9870
9871    void startAppProblemLocked(ProcessRecord app) {
9872        if (app.userId == mCurrentUserId) {
9873            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9874                    mContext, app.info.packageName, app.info.flags);
9875        } else {
9876            // If this app is not running under the current user, then we
9877            // can't give it a report button because that would require
9878            // launching the report UI under a different user.
9879            app.errorReportReceiver = null;
9880        }
9881        skipCurrentReceiverLocked(app);
9882    }
9883
9884    void skipCurrentReceiverLocked(ProcessRecord app) {
9885        for (BroadcastQueue queue : mBroadcastQueues) {
9886            queue.skipCurrentReceiverLocked(app);
9887        }
9888    }
9889
9890    /**
9891     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9892     * The application process will exit immediately after this call returns.
9893     * @param app object of the crashing app, null for the system server
9894     * @param crashInfo describing the exception
9895     */
9896    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9897        ProcessRecord r = findAppProcess(app, "Crash");
9898        final String processName = app == null ? "system_server"
9899                : (r == null ? "unknown" : r.processName);
9900
9901        handleApplicationCrashInner("crash", r, processName, crashInfo);
9902    }
9903
9904    /* Native crash reporting uses this inner version because it needs to be somewhat
9905     * decoupled from the AM-managed cleanup lifecycle
9906     */
9907    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9908            ApplicationErrorReport.CrashInfo crashInfo) {
9909        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9910                UserHandle.getUserId(Binder.getCallingUid()), processName,
9911                r == null ? -1 : r.info.flags,
9912                crashInfo.exceptionClassName,
9913                crashInfo.exceptionMessage,
9914                crashInfo.throwFileName,
9915                crashInfo.throwLineNumber);
9916
9917        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9918
9919        crashApplication(r, crashInfo);
9920    }
9921
9922    public void handleApplicationStrictModeViolation(
9923            IBinder app,
9924            int violationMask,
9925            StrictMode.ViolationInfo info) {
9926        ProcessRecord r = findAppProcess(app, "StrictMode");
9927        if (r == null) {
9928            return;
9929        }
9930
9931        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9932            Integer stackFingerprint = info.hashCode();
9933            boolean logIt = true;
9934            synchronized (mAlreadyLoggedViolatedStacks) {
9935                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9936                    logIt = false;
9937                    // TODO: sub-sample into EventLog for these, with
9938                    // the info.durationMillis?  Then we'd get
9939                    // the relative pain numbers, without logging all
9940                    // the stack traces repeatedly.  We'd want to do
9941                    // likewise in the client code, which also does
9942                    // dup suppression, before the Binder call.
9943                } else {
9944                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9945                        mAlreadyLoggedViolatedStacks.clear();
9946                    }
9947                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9948                }
9949            }
9950            if (logIt) {
9951                logStrictModeViolationToDropBox(r, info);
9952            }
9953        }
9954
9955        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9956            AppErrorResult result = new AppErrorResult();
9957            synchronized (this) {
9958                final long origId = Binder.clearCallingIdentity();
9959
9960                Message msg = Message.obtain();
9961                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9962                HashMap<String, Object> data = new HashMap<String, Object>();
9963                data.put("result", result);
9964                data.put("app", r);
9965                data.put("violationMask", violationMask);
9966                data.put("info", info);
9967                msg.obj = data;
9968                mHandler.sendMessage(msg);
9969
9970                Binder.restoreCallingIdentity(origId);
9971            }
9972            int res = result.get();
9973            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9974        }
9975    }
9976
9977    // Depending on the policy in effect, there could be a bunch of
9978    // these in quick succession so we try to batch these together to
9979    // minimize disk writes, number of dropbox entries, and maximize
9980    // compression, by having more fewer, larger records.
9981    private void logStrictModeViolationToDropBox(
9982            ProcessRecord process,
9983            StrictMode.ViolationInfo info) {
9984        if (info == null) {
9985            return;
9986        }
9987        final boolean isSystemApp = process == null ||
9988                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9989                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9990        final String processName = process == null ? "unknown" : process.processName;
9991        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9992        final DropBoxManager dbox = (DropBoxManager)
9993                mContext.getSystemService(Context.DROPBOX_SERVICE);
9994
9995        // Exit early if the dropbox isn't configured to accept this report type.
9996        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9997
9998        boolean bufferWasEmpty;
9999        boolean needsFlush;
10000        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10001        synchronized (sb) {
10002            bufferWasEmpty = sb.length() == 0;
10003            appendDropBoxProcessHeaders(process, processName, sb);
10004            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10005            sb.append("System-App: ").append(isSystemApp).append("\n");
10006            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10007            if (info.violationNumThisLoop != 0) {
10008                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10009            }
10010            if (info.numAnimationsRunning != 0) {
10011                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10012            }
10013            if (info.broadcastIntentAction != null) {
10014                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10015            }
10016            if (info.durationMillis != -1) {
10017                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10018            }
10019            if (info.numInstances != -1) {
10020                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10021            }
10022            if (info.tags != null) {
10023                for (String tag : info.tags) {
10024                    sb.append("Span-Tag: ").append(tag).append("\n");
10025                }
10026            }
10027            sb.append("\n");
10028            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10029                sb.append(info.crashInfo.stackTrace);
10030            }
10031            sb.append("\n");
10032
10033            // Only buffer up to ~64k.  Various logging bits truncate
10034            // things at 128k.
10035            needsFlush = (sb.length() > 64 * 1024);
10036        }
10037
10038        // Flush immediately if the buffer's grown too large, or this
10039        // is a non-system app.  Non-system apps are isolated with a
10040        // different tag & policy and not batched.
10041        //
10042        // Batching is useful during internal testing with
10043        // StrictMode settings turned up high.  Without batching,
10044        // thousands of separate files could be created on boot.
10045        if (!isSystemApp || needsFlush) {
10046            new Thread("Error dump: " + dropboxTag) {
10047                @Override
10048                public void run() {
10049                    String report;
10050                    synchronized (sb) {
10051                        report = sb.toString();
10052                        sb.delete(0, sb.length());
10053                        sb.trimToSize();
10054                    }
10055                    if (report.length() != 0) {
10056                        dbox.addText(dropboxTag, report);
10057                    }
10058                }
10059            }.start();
10060            return;
10061        }
10062
10063        // System app batching:
10064        if (!bufferWasEmpty) {
10065            // An existing dropbox-writing thread is outstanding, so
10066            // we don't need to start it up.  The existing thread will
10067            // catch the buffer appends we just did.
10068            return;
10069        }
10070
10071        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10072        // (After this point, we shouldn't access AMS internal data structures.)
10073        new Thread("Error dump: " + dropboxTag) {
10074            @Override
10075            public void run() {
10076                // 5 second sleep to let stacks arrive and be batched together
10077                try {
10078                    Thread.sleep(5000);  // 5 seconds
10079                } catch (InterruptedException e) {}
10080
10081                String errorReport;
10082                synchronized (mStrictModeBuffer) {
10083                    errorReport = mStrictModeBuffer.toString();
10084                    if (errorReport.length() == 0) {
10085                        return;
10086                    }
10087                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10088                    mStrictModeBuffer.trimToSize();
10089                }
10090                dbox.addText(dropboxTag, errorReport);
10091            }
10092        }.start();
10093    }
10094
10095    /**
10096     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10097     * @param app object of the crashing app, null for the system server
10098     * @param tag reported by the caller
10099     * @param crashInfo describing the context of the error
10100     * @return true if the process should exit immediately (WTF is fatal)
10101     */
10102    public boolean handleApplicationWtf(IBinder app, String tag,
10103            ApplicationErrorReport.CrashInfo crashInfo) {
10104        ProcessRecord r = findAppProcess(app, "WTF");
10105        final String processName = app == null ? "system_server"
10106                : (r == null ? "unknown" : r.processName);
10107
10108        EventLog.writeEvent(EventLogTags.AM_WTF,
10109                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10110                processName,
10111                r == null ? -1 : r.info.flags,
10112                tag, crashInfo.exceptionMessage);
10113
10114        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10115
10116        if (r != null && r.pid != Process.myPid() &&
10117                Settings.Global.getInt(mContext.getContentResolver(),
10118                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10119            crashApplication(r, crashInfo);
10120            return true;
10121        } else {
10122            return false;
10123        }
10124    }
10125
10126    /**
10127     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10128     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10129     */
10130    private ProcessRecord findAppProcess(IBinder app, String reason) {
10131        if (app == null) {
10132            return null;
10133        }
10134
10135        synchronized (this) {
10136            final int NP = mProcessNames.getMap().size();
10137            for (int ip=0; ip<NP; ip++) {
10138                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10139                final int NA = apps.size();
10140                for (int ia=0; ia<NA; ia++) {
10141                    ProcessRecord p = apps.valueAt(ia);
10142                    if (p.thread != null && p.thread.asBinder() == app) {
10143                        return p;
10144                    }
10145                }
10146            }
10147
10148            Slog.w(TAG, "Can't find mystery application for " + reason
10149                    + " from pid=" + Binder.getCallingPid()
10150                    + " uid=" + Binder.getCallingUid() + ": " + app);
10151            return null;
10152        }
10153    }
10154
10155    /**
10156     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10157     * to append various headers to the dropbox log text.
10158     */
10159    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10160            StringBuilder sb) {
10161        // Watchdog thread ends up invoking this function (with
10162        // a null ProcessRecord) to add the stack file to dropbox.
10163        // Do not acquire a lock on this (am) in such cases, as it
10164        // could cause a potential deadlock, if and when watchdog
10165        // is invoked due to unavailability of lock on am and it
10166        // would prevent watchdog from killing system_server.
10167        if (process == null) {
10168            sb.append("Process: ").append(processName).append("\n");
10169            return;
10170        }
10171        // Note: ProcessRecord 'process' is guarded by the service
10172        // instance.  (notably process.pkgList, which could otherwise change
10173        // concurrently during execution of this method)
10174        synchronized (this) {
10175            sb.append("Process: ").append(processName).append("\n");
10176            int flags = process.info.flags;
10177            IPackageManager pm = AppGlobals.getPackageManager();
10178            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10179            for (int ip=0; ip<process.pkgList.size(); ip++) {
10180                String pkg = process.pkgList.keyAt(ip);
10181                sb.append("Package: ").append(pkg);
10182                try {
10183                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10184                    if (pi != null) {
10185                        sb.append(" v").append(pi.versionCode);
10186                        if (pi.versionName != null) {
10187                            sb.append(" (").append(pi.versionName).append(")");
10188                        }
10189                    }
10190                } catch (RemoteException e) {
10191                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10192                }
10193                sb.append("\n");
10194            }
10195        }
10196    }
10197
10198    private static String processClass(ProcessRecord process) {
10199        if (process == null || process.pid == MY_PID) {
10200            return "system_server";
10201        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10202            return "system_app";
10203        } else {
10204            return "data_app";
10205        }
10206    }
10207
10208    /**
10209     * Write a description of an error (crash, WTF, ANR) to the drop box.
10210     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10211     * @param process which caused the error, null means the system server
10212     * @param activity which triggered the error, null if unknown
10213     * @param parent activity related to the error, null if unknown
10214     * @param subject line related to the error, null if absent
10215     * @param report in long form describing the error, null if absent
10216     * @param logFile to include in the report, null if none
10217     * @param crashInfo giving an application stack trace, null if absent
10218     */
10219    public void addErrorToDropBox(String eventType,
10220            ProcessRecord process, String processName, ActivityRecord activity,
10221            ActivityRecord parent, String subject,
10222            final String report, final File logFile,
10223            final ApplicationErrorReport.CrashInfo crashInfo) {
10224        // NOTE -- this must never acquire the ActivityManagerService lock,
10225        // otherwise the watchdog may be prevented from resetting the system.
10226
10227        final String dropboxTag = processClass(process) + "_" + eventType;
10228        final DropBoxManager dbox = (DropBoxManager)
10229                mContext.getSystemService(Context.DROPBOX_SERVICE);
10230
10231        // Exit early if the dropbox isn't configured to accept this report type.
10232        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10233
10234        final StringBuilder sb = new StringBuilder(1024);
10235        appendDropBoxProcessHeaders(process, processName, sb);
10236        if (activity != null) {
10237            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10238        }
10239        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10240            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10241        }
10242        if (parent != null && parent != activity) {
10243            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10244        }
10245        if (subject != null) {
10246            sb.append("Subject: ").append(subject).append("\n");
10247        }
10248        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10249        if (Debug.isDebuggerConnected()) {
10250            sb.append("Debugger: Connected\n");
10251        }
10252        sb.append("\n");
10253
10254        // Do the rest in a worker thread to avoid blocking the caller on I/O
10255        // (After this point, we shouldn't access AMS internal data structures.)
10256        Thread worker = new Thread("Error dump: " + dropboxTag) {
10257            @Override
10258            public void run() {
10259                if (report != null) {
10260                    sb.append(report);
10261                }
10262                if (logFile != null) {
10263                    try {
10264                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10265                                    "\n\n[[TRUNCATED]]"));
10266                    } catch (IOException e) {
10267                        Slog.e(TAG, "Error reading " + logFile, e);
10268                    }
10269                }
10270                if (crashInfo != null && crashInfo.stackTrace != null) {
10271                    sb.append(crashInfo.stackTrace);
10272                }
10273
10274                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10275                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10276                if (lines > 0) {
10277                    sb.append("\n");
10278
10279                    // Merge several logcat streams, and take the last N lines
10280                    InputStreamReader input = null;
10281                    try {
10282                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10283                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10284                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10285
10286                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10287                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10288                        input = new InputStreamReader(logcat.getInputStream());
10289
10290                        int num;
10291                        char[] buf = new char[8192];
10292                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10293                    } catch (IOException e) {
10294                        Slog.e(TAG, "Error running logcat", e);
10295                    } finally {
10296                        if (input != null) try { input.close(); } catch (IOException e) {}
10297                    }
10298                }
10299
10300                dbox.addText(dropboxTag, sb.toString());
10301            }
10302        };
10303
10304        if (process == null) {
10305            // If process is null, we are being called from some internal code
10306            // and may be about to die -- run this synchronously.
10307            worker.run();
10308        } else {
10309            worker.start();
10310        }
10311    }
10312
10313    /**
10314     * Bring up the "unexpected error" dialog box for a crashing app.
10315     * Deal with edge cases (intercepts from instrumented applications,
10316     * ActivityController, error intent receivers, that sort of thing).
10317     * @param r the application crashing
10318     * @param crashInfo describing the failure
10319     */
10320    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10321        long timeMillis = System.currentTimeMillis();
10322        String shortMsg = crashInfo.exceptionClassName;
10323        String longMsg = crashInfo.exceptionMessage;
10324        String stackTrace = crashInfo.stackTrace;
10325        if (shortMsg != null && longMsg != null) {
10326            longMsg = shortMsg + ": " + longMsg;
10327        } else if (shortMsg != null) {
10328            longMsg = shortMsg;
10329        }
10330
10331        AppErrorResult result = new AppErrorResult();
10332        synchronized (this) {
10333            if (mController != null) {
10334                try {
10335                    String name = r != null ? r.processName : null;
10336                    int pid = r != null ? r.pid : Binder.getCallingPid();
10337                    if (!mController.appCrashed(name, pid,
10338                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10339                        Slog.w(TAG, "Force-killing crashed app " + name
10340                                + " at watcher's request");
10341                        Process.killProcess(pid);
10342                        return;
10343                    }
10344                } catch (RemoteException e) {
10345                    mController = null;
10346                    Watchdog.getInstance().setActivityController(null);
10347                }
10348            }
10349
10350            final long origId = Binder.clearCallingIdentity();
10351
10352            // If this process is running instrumentation, finish it.
10353            if (r != null && r.instrumentationClass != null) {
10354                Slog.w(TAG, "Error in app " + r.processName
10355                      + " running instrumentation " + r.instrumentationClass + ":");
10356                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10357                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10358                Bundle info = new Bundle();
10359                info.putString("shortMsg", shortMsg);
10360                info.putString("longMsg", longMsg);
10361                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10362                Binder.restoreCallingIdentity(origId);
10363                return;
10364            }
10365
10366            // If we can't identify the process or it's already exceeded its crash quota,
10367            // quit right away without showing a crash dialog.
10368            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10369                Binder.restoreCallingIdentity(origId);
10370                return;
10371            }
10372
10373            Message msg = Message.obtain();
10374            msg.what = SHOW_ERROR_MSG;
10375            HashMap data = new HashMap();
10376            data.put("result", result);
10377            data.put("app", r);
10378            msg.obj = data;
10379            mHandler.sendMessage(msg);
10380
10381            Binder.restoreCallingIdentity(origId);
10382        }
10383
10384        int res = result.get();
10385
10386        Intent appErrorIntent = null;
10387        synchronized (this) {
10388            if (r != null && !r.isolated) {
10389                // XXX Can't keep track of crash time for isolated processes,
10390                // since they don't have a persistent identity.
10391                mProcessCrashTimes.put(r.info.processName, r.uid,
10392                        SystemClock.uptimeMillis());
10393            }
10394            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10395                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10396            }
10397        }
10398
10399        if (appErrorIntent != null) {
10400            try {
10401                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10402            } catch (ActivityNotFoundException e) {
10403                Slog.w(TAG, "bug report receiver dissappeared", e);
10404            }
10405        }
10406    }
10407
10408    Intent createAppErrorIntentLocked(ProcessRecord r,
10409            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10410        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10411        if (report == null) {
10412            return null;
10413        }
10414        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10415        result.setComponent(r.errorReportReceiver);
10416        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10417        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10418        return result;
10419    }
10420
10421    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10422            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10423        if (r.errorReportReceiver == null) {
10424            return null;
10425        }
10426
10427        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10428            return null;
10429        }
10430
10431        ApplicationErrorReport report = new ApplicationErrorReport();
10432        report.packageName = r.info.packageName;
10433        report.installerPackageName = r.errorReportReceiver.getPackageName();
10434        report.processName = r.processName;
10435        report.time = timeMillis;
10436        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10437
10438        if (r.crashing || r.forceCrashReport) {
10439            report.type = ApplicationErrorReport.TYPE_CRASH;
10440            report.crashInfo = crashInfo;
10441        } else if (r.notResponding) {
10442            report.type = ApplicationErrorReport.TYPE_ANR;
10443            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10444
10445            report.anrInfo.activity = r.notRespondingReport.tag;
10446            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10447            report.anrInfo.info = r.notRespondingReport.longMsg;
10448        }
10449
10450        return report;
10451    }
10452
10453    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10454        enforceNotIsolatedCaller("getProcessesInErrorState");
10455        // assume our apps are happy - lazy create the list
10456        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10457
10458        final boolean allUsers = ActivityManager.checkUidPermission(
10459                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10460                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10461        int userId = UserHandle.getUserId(Binder.getCallingUid());
10462
10463        synchronized (this) {
10464
10465            // iterate across all processes
10466            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10467                ProcessRecord app = mLruProcesses.get(i);
10468                if (!allUsers && app.userId != userId) {
10469                    continue;
10470                }
10471                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10472                    // This one's in trouble, so we'll generate a report for it
10473                    // crashes are higher priority (in case there's a crash *and* an anr)
10474                    ActivityManager.ProcessErrorStateInfo report = null;
10475                    if (app.crashing) {
10476                        report = app.crashingReport;
10477                    } else if (app.notResponding) {
10478                        report = app.notRespondingReport;
10479                    }
10480
10481                    if (report != null) {
10482                        if (errList == null) {
10483                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10484                        }
10485                        errList.add(report);
10486                    } else {
10487                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10488                                " crashing = " + app.crashing +
10489                                " notResponding = " + app.notResponding);
10490                    }
10491                }
10492            }
10493        }
10494
10495        return errList;
10496    }
10497
10498    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10499        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10500            if (currApp != null) {
10501                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10502            }
10503            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10504        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10505            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10506        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10507            if (currApp != null) {
10508                currApp.lru = 0;
10509            }
10510            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10511        } else if (adj >= ProcessList.SERVICE_ADJ) {
10512            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10513        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10514            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10515        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10516            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10517        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10518            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10519        } else {
10520            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10521        }
10522    }
10523
10524    private void fillInProcMemInfo(ProcessRecord app,
10525            ActivityManager.RunningAppProcessInfo outInfo) {
10526        outInfo.pid = app.pid;
10527        outInfo.uid = app.info.uid;
10528        if (mHeavyWeightProcess == app) {
10529            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10530        }
10531        if (app.persistent) {
10532            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10533        }
10534        if (app.activities.size() > 0) {
10535            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10536        }
10537        outInfo.lastTrimLevel = app.trimMemoryLevel;
10538        int adj = app.curAdj;
10539        outInfo.importance = oomAdjToImportance(adj, outInfo);
10540        outInfo.importanceReasonCode = app.adjTypeCode;
10541        outInfo.processState = app.curProcState;
10542    }
10543
10544    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10545        enforceNotIsolatedCaller("getRunningAppProcesses");
10546        // Lazy instantiation of list
10547        List<ActivityManager.RunningAppProcessInfo> runList = null;
10548        final boolean allUsers = ActivityManager.checkUidPermission(
10549                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10550                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10551        int userId = UserHandle.getUserId(Binder.getCallingUid());
10552        synchronized (this) {
10553            // Iterate across all processes
10554            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10555                ProcessRecord app = mLruProcesses.get(i);
10556                if (!allUsers && app.userId != userId) {
10557                    continue;
10558                }
10559                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10560                    // Generate process state info for running application
10561                    ActivityManager.RunningAppProcessInfo currApp =
10562                        new ActivityManager.RunningAppProcessInfo(app.processName,
10563                                app.pid, app.getPackageList());
10564                    fillInProcMemInfo(app, currApp);
10565                    if (app.adjSource instanceof ProcessRecord) {
10566                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10567                        currApp.importanceReasonImportance = oomAdjToImportance(
10568                                app.adjSourceOom, null);
10569                    } else if (app.adjSource instanceof ActivityRecord) {
10570                        ActivityRecord r = (ActivityRecord)app.adjSource;
10571                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10572                    }
10573                    if (app.adjTarget instanceof ComponentName) {
10574                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10575                    }
10576                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10577                    //        + " lru=" + currApp.lru);
10578                    if (runList == null) {
10579                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10580                    }
10581                    runList.add(currApp);
10582                }
10583            }
10584        }
10585        return runList;
10586    }
10587
10588    public List<ApplicationInfo> getRunningExternalApplications() {
10589        enforceNotIsolatedCaller("getRunningExternalApplications");
10590        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10591        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10592        if (runningApps != null && runningApps.size() > 0) {
10593            Set<String> extList = new HashSet<String>();
10594            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10595                if (app.pkgList != null) {
10596                    for (String pkg : app.pkgList) {
10597                        extList.add(pkg);
10598                    }
10599                }
10600            }
10601            IPackageManager pm = AppGlobals.getPackageManager();
10602            for (String pkg : extList) {
10603                try {
10604                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10605                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10606                        retList.add(info);
10607                    }
10608                } catch (RemoteException e) {
10609                }
10610            }
10611        }
10612        return retList;
10613    }
10614
10615    @Override
10616    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10617        enforceNotIsolatedCaller("getMyMemoryState");
10618        synchronized (this) {
10619            ProcessRecord proc;
10620            synchronized (mPidsSelfLocked) {
10621                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10622            }
10623            fillInProcMemInfo(proc, outInfo);
10624        }
10625    }
10626
10627    @Override
10628    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10629        if (checkCallingPermission(android.Manifest.permission.DUMP)
10630                != PackageManager.PERMISSION_GRANTED) {
10631            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10632                    + Binder.getCallingPid()
10633                    + ", uid=" + Binder.getCallingUid()
10634                    + " without permission "
10635                    + android.Manifest.permission.DUMP);
10636            return;
10637        }
10638
10639        boolean dumpAll = false;
10640        boolean dumpClient = false;
10641        String dumpPackage = null;
10642
10643        int opti = 0;
10644        while (opti < args.length) {
10645            String opt = args[opti];
10646            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10647                break;
10648            }
10649            opti++;
10650            if ("-a".equals(opt)) {
10651                dumpAll = true;
10652            } else if ("-c".equals(opt)) {
10653                dumpClient = true;
10654            } else if ("-h".equals(opt)) {
10655                pw.println("Activity manager dump options:");
10656                pw.println("  [-a] [-c] [-h] [cmd] ...");
10657                pw.println("  cmd may be one of:");
10658                pw.println("    a[ctivities]: activity stack state");
10659                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10660                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10661                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10662                pw.println("    o[om]: out of memory management");
10663                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10664                pw.println("    provider [COMP_SPEC]: provider client-side state");
10665                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10666                pw.println("    service [COMP_SPEC]: service client-side state");
10667                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10668                pw.println("    all: dump all activities");
10669                pw.println("    top: dump the top activity");
10670                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10671                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10672                pw.println("    a partial substring in a component name, a");
10673                pw.println("    hex object identifier.");
10674                pw.println("  -a: include all available server state.");
10675                pw.println("  -c: include client state.");
10676                return;
10677            } else {
10678                pw.println("Unknown argument: " + opt + "; use -h for help");
10679            }
10680        }
10681
10682        long origId = Binder.clearCallingIdentity();
10683        boolean more = false;
10684        // Is the caller requesting to dump a particular piece of data?
10685        if (opti < args.length) {
10686            String cmd = args[opti];
10687            opti++;
10688            if ("activities".equals(cmd) || "a".equals(cmd)) {
10689                synchronized (this) {
10690                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10691                }
10692            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10693                String[] newArgs;
10694                String name;
10695                if (opti >= args.length) {
10696                    name = null;
10697                    newArgs = EMPTY_STRING_ARRAY;
10698                } else {
10699                    name = args[opti];
10700                    opti++;
10701                    newArgs = new String[args.length - opti];
10702                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10703                            args.length - opti);
10704                }
10705                synchronized (this) {
10706                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10707                }
10708            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10709                String[] newArgs;
10710                String name;
10711                if (opti >= args.length) {
10712                    name = null;
10713                    newArgs = EMPTY_STRING_ARRAY;
10714                } else {
10715                    name = args[opti];
10716                    opti++;
10717                    newArgs = new String[args.length - opti];
10718                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10719                            args.length - opti);
10720                }
10721                synchronized (this) {
10722                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10723                }
10724            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10725                String[] newArgs;
10726                String name;
10727                if (opti >= args.length) {
10728                    name = null;
10729                    newArgs = EMPTY_STRING_ARRAY;
10730                } else {
10731                    name = args[opti];
10732                    opti++;
10733                    newArgs = new String[args.length - opti];
10734                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10735                            args.length - opti);
10736                }
10737                synchronized (this) {
10738                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10739                }
10740            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10741                synchronized (this) {
10742                    dumpOomLocked(fd, pw, args, opti, true);
10743                }
10744            } else if ("provider".equals(cmd)) {
10745                String[] newArgs;
10746                String name;
10747                if (opti >= args.length) {
10748                    name = null;
10749                    newArgs = EMPTY_STRING_ARRAY;
10750                } else {
10751                    name = args[opti];
10752                    opti++;
10753                    newArgs = new String[args.length - opti];
10754                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10755                }
10756                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10757                    pw.println("No providers match: " + name);
10758                    pw.println("Use -h for help.");
10759                }
10760            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10761                synchronized (this) {
10762                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10763                }
10764            } else if ("service".equals(cmd)) {
10765                String[] newArgs;
10766                String name;
10767                if (opti >= args.length) {
10768                    name = null;
10769                    newArgs = EMPTY_STRING_ARRAY;
10770                } else {
10771                    name = args[opti];
10772                    opti++;
10773                    newArgs = new String[args.length - opti];
10774                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10775                            args.length - opti);
10776                }
10777                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10778                    pw.println("No services match: " + name);
10779                    pw.println("Use -h for help.");
10780                }
10781            } else if ("package".equals(cmd)) {
10782                String[] newArgs;
10783                if (opti >= args.length) {
10784                    pw.println("package: no package name specified");
10785                    pw.println("Use -h for help.");
10786                } else {
10787                    dumpPackage = args[opti];
10788                    opti++;
10789                    newArgs = new String[args.length - opti];
10790                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10791                            args.length - opti);
10792                    args = newArgs;
10793                    opti = 0;
10794                    more = true;
10795                }
10796            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10797                synchronized (this) {
10798                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10799                }
10800            } else {
10801                // Dumping a single activity?
10802                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10803                    pw.println("Bad activity command, or no activities match: " + cmd);
10804                    pw.println("Use -h for help.");
10805                }
10806            }
10807            if (!more) {
10808                Binder.restoreCallingIdentity(origId);
10809                return;
10810            }
10811        }
10812
10813        // No piece of data specified, dump everything.
10814        synchronized (this) {
10815            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10816            pw.println();
10817            if (dumpAll) {
10818                pw.println("-------------------------------------------------------------------------------");
10819            }
10820            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10821            pw.println();
10822            if (dumpAll) {
10823                pw.println("-------------------------------------------------------------------------------");
10824            }
10825            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10826            pw.println();
10827            if (dumpAll) {
10828                pw.println("-------------------------------------------------------------------------------");
10829            }
10830            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10831            pw.println();
10832            if (dumpAll) {
10833                pw.println("-------------------------------------------------------------------------------");
10834            }
10835            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10836            pw.println();
10837            if (dumpAll) {
10838                pw.println("-------------------------------------------------------------------------------");
10839            }
10840            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10841        }
10842        Binder.restoreCallingIdentity(origId);
10843    }
10844
10845    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10846            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10847        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10848
10849        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10850                dumpPackage);
10851        boolean needSep = printedAnything;
10852
10853        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10854                dumpPackage, needSep, "  mFocusedActivity: ");
10855        if (printed) {
10856            printedAnything = true;
10857            needSep = false;
10858        }
10859
10860        if (dumpPackage == null) {
10861            if (needSep) {
10862                pw.println();
10863            }
10864            needSep = true;
10865            printedAnything = true;
10866            mStackSupervisor.dump(pw, "  ");
10867        }
10868
10869        if (mRecentTasks.size() > 0) {
10870            boolean printedHeader = false;
10871
10872            final int N = mRecentTasks.size();
10873            for (int i=0; i<N; i++) {
10874                TaskRecord tr = mRecentTasks.get(i);
10875                if (dumpPackage != null) {
10876                    if (tr.realActivity == null ||
10877                            !dumpPackage.equals(tr.realActivity)) {
10878                        continue;
10879                    }
10880                }
10881                if (!printedHeader) {
10882                    if (needSep) {
10883                        pw.println();
10884                    }
10885                    pw.println("  Recent tasks:");
10886                    printedHeader = true;
10887                    printedAnything = true;
10888                }
10889                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10890                        pw.println(tr);
10891                if (dumpAll) {
10892                    mRecentTasks.get(i).dump(pw, "    ");
10893                }
10894            }
10895        }
10896
10897        if (!printedAnything) {
10898            pw.println("  (nothing)");
10899        }
10900    }
10901
10902    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10903            int opti, boolean dumpAll, String dumpPackage) {
10904        boolean needSep = false;
10905        boolean printedAnything = false;
10906        int numPers = 0;
10907
10908        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10909
10910        if (dumpAll) {
10911            final int NP = mProcessNames.getMap().size();
10912            for (int ip=0; ip<NP; ip++) {
10913                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10914                final int NA = procs.size();
10915                for (int ia=0; ia<NA; ia++) {
10916                    ProcessRecord r = procs.valueAt(ia);
10917                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10918                        continue;
10919                    }
10920                    if (!needSep) {
10921                        pw.println("  All known processes:");
10922                        needSep = true;
10923                        printedAnything = true;
10924                    }
10925                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10926                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10927                        pw.print(" "); pw.println(r);
10928                    r.dump(pw, "    ");
10929                    if (r.persistent) {
10930                        numPers++;
10931                    }
10932                }
10933            }
10934        }
10935
10936        if (mIsolatedProcesses.size() > 0) {
10937            boolean printed = false;
10938            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10939                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10940                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10941                    continue;
10942                }
10943                if (!printed) {
10944                    if (needSep) {
10945                        pw.println();
10946                    }
10947                    pw.println("  Isolated process list (sorted by uid):");
10948                    printedAnything = true;
10949                    printed = true;
10950                    needSep = true;
10951                }
10952                pw.println(String.format("%sIsolated #%2d: %s",
10953                        "    ", i, r.toString()));
10954            }
10955        }
10956
10957        if (mLruProcesses.size() > 0) {
10958            if (needSep) {
10959                pw.println();
10960            }
10961            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10962                    pw.print(" total, non-act at ");
10963                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10964                    pw.print(", non-svc at ");
10965                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10966                    pw.println("):");
10967            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10968            needSep = true;
10969            printedAnything = true;
10970        }
10971
10972        if (dumpAll || dumpPackage != null) {
10973            synchronized (mPidsSelfLocked) {
10974                boolean printed = false;
10975                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10976                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10977                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10978                        continue;
10979                    }
10980                    if (!printed) {
10981                        if (needSep) pw.println();
10982                        needSep = true;
10983                        pw.println("  PID mappings:");
10984                        printed = true;
10985                        printedAnything = true;
10986                    }
10987                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10988                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10989                }
10990            }
10991        }
10992
10993        if (mForegroundProcesses.size() > 0) {
10994            synchronized (mPidsSelfLocked) {
10995                boolean printed = false;
10996                for (int i=0; i<mForegroundProcesses.size(); i++) {
10997                    ProcessRecord r = mPidsSelfLocked.get(
10998                            mForegroundProcesses.valueAt(i).pid);
10999                    if (dumpPackage != null && (r == null
11000                            || !r.pkgList.containsKey(dumpPackage))) {
11001                        continue;
11002                    }
11003                    if (!printed) {
11004                        if (needSep) pw.println();
11005                        needSep = true;
11006                        pw.println("  Foreground Processes:");
11007                        printed = true;
11008                        printedAnything = true;
11009                    }
11010                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11011                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11012                }
11013            }
11014        }
11015
11016        if (mPersistentStartingProcesses.size() > 0) {
11017            if (needSep) pw.println();
11018            needSep = true;
11019            printedAnything = true;
11020            pw.println("  Persisent processes that are starting:");
11021            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11022                    "Starting Norm", "Restarting PERS", dumpPackage);
11023        }
11024
11025        if (mRemovedProcesses.size() > 0) {
11026            if (needSep) pw.println();
11027            needSep = true;
11028            printedAnything = true;
11029            pw.println("  Processes that are being removed:");
11030            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11031                    "Removed Norm", "Removed PERS", dumpPackage);
11032        }
11033
11034        if (mProcessesOnHold.size() > 0) {
11035            if (needSep) pw.println();
11036            needSep = true;
11037            printedAnything = true;
11038            pw.println("  Processes that are on old until the system is ready:");
11039            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11040                    "OnHold Norm", "OnHold PERS", dumpPackage);
11041        }
11042
11043        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11044
11045        if (mProcessCrashTimes.getMap().size() > 0) {
11046            boolean printed = false;
11047            long now = SystemClock.uptimeMillis();
11048            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11049            final int NP = pmap.size();
11050            for (int ip=0; ip<NP; ip++) {
11051                String pname = pmap.keyAt(ip);
11052                SparseArray<Long> uids = pmap.valueAt(ip);
11053                final int N = uids.size();
11054                for (int i=0; i<N; i++) {
11055                    int puid = uids.keyAt(i);
11056                    ProcessRecord r = mProcessNames.get(pname, puid);
11057                    if (dumpPackage != null && (r == null
11058                            || !r.pkgList.containsKey(dumpPackage))) {
11059                        continue;
11060                    }
11061                    if (!printed) {
11062                        if (needSep) pw.println();
11063                        needSep = true;
11064                        pw.println("  Time since processes crashed:");
11065                        printed = true;
11066                        printedAnything = true;
11067                    }
11068                    pw.print("    Process "); pw.print(pname);
11069                            pw.print(" uid "); pw.print(puid);
11070                            pw.print(": last crashed ");
11071                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11072                            pw.println(" ago");
11073                }
11074            }
11075        }
11076
11077        if (mBadProcesses.getMap().size() > 0) {
11078            boolean printed = false;
11079            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11080            final int NP = pmap.size();
11081            for (int ip=0; ip<NP; ip++) {
11082                String pname = pmap.keyAt(ip);
11083                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11084                final int N = uids.size();
11085                for (int i=0; i<N; i++) {
11086                    int puid = uids.keyAt(i);
11087                    ProcessRecord r = mProcessNames.get(pname, puid);
11088                    if (dumpPackage != null && (r == null
11089                            || !r.pkgList.containsKey(dumpPackage))) {
11090                        continue;
11091                    }
11092                    if (!printed) {
11093                        if (needSep) pw.println();
11094                        needSep = true;
11095                        pw.println("  Bad processes:");
11096                        printedAnything = true;
11097                    }
11098                    BadProcessInfo info = uids.valueAt(i);
11099                    pw.print("    Bad process "); pw.print(pname);
11100                            pw.print(" uid "); pw.print(puid);
11101                            pw.print(": crashed at time "); pw.println(info.time);
11102                    if (info.shortMsg != null) {
11103                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11104                    }
11105                    if (info.longMsg != null) {
11106                        pw.print("      Long msg: "); pw.println(info.longMsg);
11107                    }
11108                    if (info.stack != null) {
11109                        pw.println("      Stack:");
11110                        int lastPos = 0;
11111                        for (int pos=0; pos<info.stack.length(); pos++) {
11112                            if (info.stack.charAt(pos) == '\n') {
11113                                pw.print("        ");
11114                                pw.write(info.stack, lastPos, pos-lastPos);
11115                                pw.println();
11116                                lastPos = pos+1;
11117                            }
11118                        }
11119                        if (lastPos < info.stack.length()) {
11120                            pw.print("        ");
11121                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11122                            pw.println();
11123                        }
11124                    }
11125                }
11126            }
11127        }
11128
11129        if (dumpPackage == null) {
11130            pw.println();
11131            needSep = false;
11132            pw.println("  mStartedUsers:");
11133            for (int i=0; i<mStartedUsers.size(); i++) {
11134                UserStartedState uss = mStartedUsers.valueAt(i);
11135                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11136                        pw.print(": "); uss.dump("", pw);
11137            }
11138            pw.print("  mStartedUserArray: [");
11139            for (int i=0; i<mStartedUserArray.length; i++) {
11140                if (i > 0) pw.print(", ");
11141                pw.print(mStartedUserArray[i]);
11142            }
11143            pw.println("]");
11144            pw.print("  mUserLru: [");
11145            for (int i=0; i<mUserLru.size(); i++) {
11146                if (i > 0) pw.print(", ");
11147                pw.print(mUserLru.get(i));
11148            }
11149            pw.println("]");
11150            if (dumpAll) {
11151                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11152            }
11153        }
11154        if (mHomeProcess != null && (dumpPackage == null
11155                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11156            if (needSep) {
11157                pw.println();
11158                needSep = false;
11159            }
11160            pw.println("  mHomeProcess: " + mHomeProcess);
11161        }
11162        if (mPreviousProcess != null && (dumpPackage == null
11163                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11164            if (needSep) {
11165                pw.println();
11166                needSep = false;
11167            }
11168            pw.println("  mPreviousProcess: " + mPreviousProcess);
11169        }
11170        if (dumpAll) {
11171            StringBuilder sb = new StringBuilder(128);
11172            sb.append("  mPreviousProcessVisibleTime: ");
11173            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11174            pw.println(sb);
11175        }
11176        if (mHeavyWeightProcess != null && (dumpPackage == null
11177                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11178            if (needSep) {
11179                pw.println();
11180                needSep = false;
11181            }
11182            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11183        }
11184        if (dumpPackage == null) {
11185            pw.println("  mConfiguration: " + mConfiguration);
11186        }
11187        if (dumpAll) {
11188            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11189            if (mCompatModePackages.getPackages().size() > 0) {
11190                boolean printed = false;
11191                for (Map.Entry<String, Integer> entry
11192                        : mCompatModePackages.getPackages().entrySet()) {
11193                    String pkg = entry.getKey();
11194                    int mode = entry.getValue();
11195                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11196                        continue;
11197                    }
11198                    if (!printed) {
11199                        pw.println("  mScreenCompatPackages:");
11200                        printed = true;
11201                    }
11202                    pw.print("    "); pw.print(pkg); pw.print(": ");
11203                            pw.print(mode); pw.println();
11204                }
11205            }
11206        }
11207        if (dumpPackage == null) {
11208            if (mSleeping || mWentToSleep || mLockScreenShown) {
11209                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11210                        + " mLockScreenShown " + mLockScreenShown);
11211            }
11212            if (mShuttingDown || mRunningVoice) {
11213                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11214            }
11215        }
11216        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11217                || mOrigWaitForDebugger) {
11218            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11219                    || dumpPackage.equals(mOrigDebugApp)) {
11220                if (needSep) {
11221                    pw.println();
11222                    needSep = false;
11223                }
11224                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11225                        + " mDebugTransient=" + mDebugTransient
11226                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11227            }
11228        }
11229        if (mOpenGlTraceApp != null) {
11230            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11231                if (needSep) {
11232                    pw.println();
11233                    needSep = false;
11234                }
11235                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11236            }
11237        }
11238        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11239                || mProfileFd != null) {
11240            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11241                if (needSep) {
11242                    pw.println();
11243                    needSep = false;
11244                }
11245                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11246                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11247                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11248                        + mAutoStopProfiler);
11249            }
11250        }
11251        if (dumpPackage == null) {
11252            if (mAlwaysFinishActivities || mController != null) {
11253                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11254                        + " mController=" + mController);
11255            }
11256            if (dumpAll) {
11257                pw.println("  Total persistent processes: " + numPers);
11258                pw.println("  mProcessesReady=" + mProcessesReady
11259                        + " mSystemReady=" + mSystemReady);
11260                pw.println("  mBooting=" + mBooting
11261                        + " mBooted=" + mBooted
11262                        + " mFactoryTest=" + mFactoryTest);
11263                pw.print("  mLastPowerCheckRealtime=");
11264                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11265                        pw.println("");
11266                pw.print("  mLastPowerCheckUptime=");
11267                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11268                        pw.println("");
11269                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11270                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11271                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11272                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11273                        + " (" + mLruProcesses.size() + " total)"
11274                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11275                        + " mNumServiceProcs=" + mNumServiceProcs
11276                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11277                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11278                        + " mLastMemoryLevel" + mLastMemoryLevel
11279                        + " mLastNumProcesses" + mLastNumProcesses);
11280                long now = SystemClock.uptimeMillis();
11281                pw.print("  mLastIdleTime=");
11282                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11283                        pw.print(" mLowRamSinceLastIdle=");
11284                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11285                        pw.println();
11286            }
11287        }
11288
11289        if (!printedAnything) {
11290            pw.println("  (nothing)");
11291        }
11292    }
11293
11294    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11295            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11296        if (mProcessesToGc.size() > 0) {
11297            boolean printed = false;
11298            long now = SystemClock.uptimeMillis();
11299            for (int i=0; i<mProcessesToGc.size(); i++) {
11300                ProcessRecord proc = mProcessesToGc.get(i);
11301                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11302                    continue;
11303                }
11304                if (!printed) {
11305                    if (needSep) pw.println();
11306                    needSep = true;
11307                    pw.println("  Processes that are waiting to GC:");
11308                    printed = true;
11309                }
11310                pw.print("    Process "); pw.println(proc);
11311                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11312                        pw.print(", last gced=");
11313                        pw.print(now-proc.lastRequestedGc);
11314                        pw.print(" ms ago, last lowMem=");
11315                        pw.print(now-proc.lastLowMemory);
11316                        pw.println(" ms ago");
11317
11318            }
11319        }
11320        return needSep;
11321    }
11322
11323    void printOomLevel(PrintWriter pw, String name, int adj) {
11324        pw.print("    ");
11325        if (adj >= 0) {
11326            pw.print(' ');
11327            if (adj < 10) pw.print(' ');
11328        } else {
11329            if (adj > -10) pw.print(' ');
11330        }
11331        pw.print(adj);
11332        pw.print(": ");
11333        pw.print(name);
11334        pw.print(" (");
11335        pw.print(mProcessList.getMemLevel(adj)/1024);
11336        pw.println(" kB)");
11337    }
11338
11339    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11340            int opti, boolean dumpAll) {
11341        boolean needSep = false;
11342
11343        if (mLruProcesses.size() > 0) {
11344            if (needSep) pw.println();
11345            needSep = true;
11346            pw.println("  OOM levels:");
11347            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11348            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11349            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11350            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11351            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11352            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11353            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11354            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11355            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11356            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11357            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11358            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11359            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11360
11361            if (needSep) pw.println();
11362            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11363                    pw.print(" total, non-act at ");
11364                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11365                    pw.print(", non-svc at ");
11366                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11367                    pw.println("):");
11368            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11369            needSep = true;
11370        }
11371
11372        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11373
11374        pw.println();
11375        pw.println("  mHomeProcess: " + mHomeProcess);
11376        pw.println("  mPreviousProcess: " + mPreviousProcess);
11377        if (mHeavyWeightProcess != null) {
11378            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11379        }
11380
11381        return true;
11382    }
11383
11384    /**
11385     * There are three ways to call this:
11386     *  - no provider specified: dump all the providers
11387     *  - a flattened component name that matched an existing provider was specified as the
11388     *    first arg: dump that one provider
11389     *  - the first arg isn't the flattened component name of an existing provider:
11390     *    dump all providers whose component contains the first arg as a substring
11391     */
11392    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11393            int opti, boolean dumpAll) {
11394        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11395    }
11396
11397    static class ItemMatcher {
11398        ArrayList<ComponentName> components;
11399        ArrayList<String> strings;
11400        ArrayList<Integer> objects;
11401        boolean all;
11402
11403        ItemMatcher() {
11404            all = true;
11405        }
11406
11407        void build(String name) {
11408            ComponentName componentName = ComponentName.unflattenFromString(name);
11409            if (componentName != null) {
11410                if (components == null) {
11411                    components = new ArrayList<ComponentName>();
11412                }
11413                components.add(componentName);
11414                all = false;
11415            } else {
11416                int objectId = 0;
11417                // Not a '/' separated full component name; maybe an object ID?
11418                try {
11419                    objectId = Integer.parseInt(name, 16);
11420                    if (objects == null) {
11421                        objects = new ArrayList<Integer>();
11422                    }
11423                    objects.add(objectId);
11424                    all = false;
11425                } catch (RuntimeException e) {
11426                    // Not an integer; just do string match.
11427                    if (strings == null) {
11428                        strings = new ArrayList<String>();
11429                    }
11430                    strings.add(name);
11431                    all = false;
11432                }
11433            }
11434        }
11435
11436        int build(String[] args, int opti) {
11437            for (; opti<args.length; opti++) {
11438                String name = args[opti];
11439                if ("--".equals(name)) {
11440                    return opti+1;
11441                }
11442                build(name);
11443            }
11444            return opti;
11445        }
11446
11447        boolean match(Object object, ComponentName comp) {
11448            if (all) {
11449                return true;
11450            }
11451            if (components != null) {
11452                for (int i=0; i<components.size(); i++) {
11453                    if (components.get(i).equals(comp)) {
11454                        return true;
11455                    }
11456                }
11457            }
11458            if (objects != null) {
11459                for (int i=0; i<objects.size(); i++) {
11460                    if (System.identityHashCode(object) == objects.get(i)) {
11461                        return true;
11462                    }
11463                }
11464            }
11465            if (strings != null) {
11466                String flat = comp.flattenToString();
11467                for (int i=0; i<strings.size(); i++) {
11468                    if (flat.contains(strings.get(i))) {
11469                        return true;
11470                    }
11471                }
11472            }
11473            return false;
11474        }
11475    }
11476
11477    /**
11478     * There are three things that cmd can be:
11479     *  - a flattened component name that matches an existing activity
11480     *  - the cmd arg isn't the flattened component name of an existing activity:
11481     *    dump all activity whose component contains the cmd as a substring
11482     *  - A hex number of the ActivityRecord object instance.
11483     */
11484    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11485            int opti, boolean dumpAll) {
11486        ArrayList<ActivityRecord> activities;
11487
11488        synchronized (this) {
11489            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11490        }
11491
11492        if (activities.size() <= 0) {
11493            return false;
11494        }
11495
11496        String[] newArgs = new String[args.length - opti];
11497        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11498
11499        TaskRecord lastTask = null;
11500        boolean needSep = false;
11501        for (int i=activities.size()-1; i>=0; i--) {
11502            ActivityRecord r = activities.get(i);
11503            if (needSep) {
11504                pw.println();
11505            }
11506            needSep = true;
11507            synchronized (this) {
11508                if (lastTask != r.task) {
11509                    lastTask = r.task;
11510                    pw.print("TASK "); pw.print(lastTask.affinity);
11511                            pw.print(" id="); pw.println(lastTask.taskId);
11512                    if (dumpAll) {
11513                        lastTask.dump(pw, "  ");
11514                    }
11515                }
11516            }
11517            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11518        }
11519        return true;
11520    }
11521
11522    /**
11523     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11524     * there is a thread associated with the activity.
11525     */
11526    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11527            final ActivityRecord r, String[] args, boolean dumpAll) {
11528        String innerPrefix = prefix + "  ";
11529        synchronized (this) {
11530            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11531                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11532                    pw.print(" pid=");
11533                    if (r.app != null) pw.println(r.app.pid);
11534                    else pw.println("(not running)");
11535            if (dumpAll) {
11536                r.dump(pw, innerPrefix);
11537            }
11538        }
11539        if (r.app != null && r.app.thread != null) {
11540            // flush anything that is already in the PrintWriter since the thread is going
11541            // to write to the file descriptor directly
11542            pw.flush();
11543            try {
11544                TransferPipe tp = new TransferPipe();
11545                try {
11546                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11547                            r.appToken, innerPrefix, args);
11548                    tp.go(fd);
11549                } finally {
11550                    tp.kill();
11551                }
11552            } catch (IOException e) {
11553                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11554            } catch (RemoteException e) {
11555                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11556            }
11557        }
11558    }
11559
11560    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11561            int opti, boolean dumpAll, String dumpPackage) {
11562        boolean needSep = false;
11563        boolean onlyHistory = false;
11564        boolean printedAnything = false;
11565
11566        if ("history".equals(dumpPackage)) {
11567            if (opti < args.length && "-s".equals(args[opti])) {
11568                dumpAll = false;
11569            }
11570            onlyHistory = true;
11571            dumpPackage = null;
11572        }
11573
11574        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11575        if (!onlyHistory && dumpAll) {
11576            if (mRegisteredReceivers.size() > 0) {
11577                boolean printed = false;
11578                Iterator it = mRegisteredReceivers.values().iterator();
11579                while (it.hasNext()) {
11580                    ReceiverList r = (ReceiverList)it.next();
11581                    if (dumpPackage != null && (r.app == null ||
11582                            !dumpPackage.equals(r.app.info.packageName))) {
11583                        continue;
11584                    }
11585                    if (!printed) {
11586                        pw.println("  Registered Receivers:");
11587                        needSep = true;
11588                        printed = true;
11589                        printedAnything = true;
11590                    }
11591                    pw.print("  * "); pw.println(r);
11592                    r.dump(pw, "    ");
11593                }
11594            }
11595
11596            if (mReceiverResolver.dump(pw, needSep ?
11597                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11598                    "    ", dumpPackage, false)) {
11599                needSep = true;
11600                printedAnything = true;
11601            }
11602        }
11603
11604        for (BroadcastQueue q : mBroadcastQueues) {
11605            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11606            printedAnything |= needSep;
11607        }
11608
11609        needSep = true;
11610
11611        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11612            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11613                if (needSep) {
11614                    pw.println();
11615                }
11616                needSep = true;
11617                printedAnything = true;
11618                pw.print("  Sticky broadcasts for user ");
11619                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11620                StringBuilder sb = new StringBuilder(128);
11621                for (Map.Entry<String, ArrayList<Intent>> ent
11622                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11623                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11624                    if (dumpAll) {
11625                        pw.println(":");
11626                        ArrayList<Intent> intents = ent.getValue();
11627                        final int N = intents.size();
11628                        for (int i=0; i<N; i++) {
11629                            sb.setLength(0);
11630                            sb.append("    Intent: ");
11631                            intents.get(i).toShortString(sb, false, true, false, false);
11632                            pw.println(sb.toString());
11633                            Bundle bundle = intents.get(i).getExtras();
11634                            if (bundle != null) {
11635                                pw.print("      ");
11636                                pw.println(bundle.toString());
11637                            }
11638                        }
11639                    } else {
11640                        pw.println("");
11641                    }
11642                }
11643            }
11644        }
11645
11646        if (!onlyHistory && dumpAll) {
11647            pw.println();
11648            for (BroadcastQueue queue : mBroadcastQueues) {
11649                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11650                        + queue.mBroadcastsScheduled);
11651            }
11652            pw.println("  mHandler:");
11653            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11654            needSep = true;
11655            printedAnything = true;
11656        }
11657
11658        if (!printedAnything) {
11659            pw.println("  (nothing)");
11660        }
11661    }
11662
11663    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11664            int opti, boolean dumpAll, String dumpPackage) {
11665        boolean needSep;
11666        boolean printedAnything = false;
11667
11668        ItemMatcher matcher = new ItemMatcher();
11669        matcher.build(args, opti);
11670
11671        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11672
11673        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11674        printedAnything |= needSep;
11675
11676        if (mLaunchingProviders.size() > 0) {
11677            boolean printed = false;
11678            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11679                ContentProviderRecord r = mLaunchingProviders.get(i);
11680                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11681                    continue;
11682                }
11683                if (!printed) {
11684                    if (needSep) pw.println();
11685                    needSep = true;
11686                    pw.println("  Launching content providers:");
11687                    printed = true;
11688                    printedAnything = true;
11689                }
11690                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11691                        pw.println(r);
11692            }
11693        }
11694
11695        if (mGrantedUriPermissions.size() > 0) {
11696            boolean printed = false;
11697            int dumpUid = -2;
11698            if (dumpPackage != null) {
11699                try {
11700                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11701                } catch (NameNotFoundException e) {
11702                    dumpUid = -1;
11703                }
11704            }
11705            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11706                int uid = mGrantedUriPermissions.keyAt(i);
11707                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11708                    continue;
11709                }
11710                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11711                if (!printed) {
11712                    if (needSep) pw.println();
11713                    needSep = true;
11714                    pw.println("  Granted Uri Permissions:");
11715                    printed = true;
11716                    printedAnything = true;
11717                }
11718                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11719                for (UriPermission perm : perms.values()) {
11720                    pw.print("    "); pw.println(perm);
11721                    if (dumpAll) {
11722                        perm.dump(pw, "      ");
11723                    }
11724                }
11725            }
11726        }
11727
11728        if (!printedAnything) {
11729            pw.println("  (nothing)");
11730        }
11731    }
11732
11733    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11734            int opti, boolean dumpAll, String dumpPackage) {
11735        boolean printed = false;
11736
11737        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11738
11739        if (mIntentSenderRecords.size() > 0) {
11740            Iterator<WeakReference<PendingIntentRecord>> it
11741                    = mIntentSenderRecords.values().iterator();
11742            while (it.hasNext()) {
11743                WeakReference<PendingIntentRecord> ref = it.next();
11744                PendingIntentRecord rec = ref != null ? ref.get(): null;
11745                if (dumpPackage != null && (rec == null
11746                        || !dumpPackage.equals(rec.key.packageName))) {
11747                    continue;
11748                }
11749                printed = true;
11750                if (rec != null) {
11751                    pw.print("  * "); pw.println(rec);
11752                    if (dumpAll) {
11753                        rec.dump(pw, "    ");
11754                    }
11755                } else {
11756                    pw.print("  * "); pw.println(ref);
11757                }
11758            }
11759        }
11760
11761        if (!printed) {
11762            pw.println("  (nothing)");
11763        }
11764    }
11765
11766    private static final int dumpProcessList(PrintWriter pw,
11767            ActivityManagerService service, List list,
11768            String prefix, String normalLabel, String persistentLabel,
11769            String dumpPackage) {
11770        int numPers = 0;
11771        final int N = list.size()-1;
11772        for (int i=N; i>=0; i--) {
11773            ProcessRecord r = (ProcessRecord)list.get(i);
11774            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11775                continue;
11776            }
11777            pw.println(String.format("%s%s #%2d: %s",
11778                    prefix, (r.persistent ? persistentLabel : normalLabel),
11779                    i, r.toString()));
11780            if (r.persistent) {
11781                numPers++;
11782            }
11783        }
11784        return numPers;
11785    }
11786
11787    private static final boolean dumpProcessOomList(PrintWriter pw,
11788            ActivityManagerService service, List<ProcessRecord> origList,
11789            String prefix, String normalLabel, String persistentLabel,
11790            boolean inclDetails, String dumpPackage) {
11791
11792        ArrayList<Pair<ProcessRecord, Integer>> list
11793                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11794        for (int i=0; i<origList.size(); i++) {
11795            ProcessRecord r = origList.get(i);
11796            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11797                continue;
11798            }
11799            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11800        }
11801
11802        if (list.size() <= 0) {
11803            return false;
11804        }
11805
11806        Comparator<Pair<ProcessRecord, Integer>> comparator
11807                = new Comparator<Pair<ProcessRecord, Integer>>() {
11808            @Override
11809            public int compare(Pair<ProcessRecord, Integer> object1,
11810                    Pair<ProcessRecord, Integer> object2) {
11811                if (object1.first.setAdj != object2.first.setAdj) {
11812                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11813                }
11814                if (object1.second.intValue() != object2.second.intValue()) {
11815                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11816                }
11817                return 0;
11818            }
11819        };
11820
11821        Collections.sort(list, comparator);
11822
11823        final long curRealtime = SystemClock.elapsedRealtime();
11824        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11825        final long curUptime = SystemClock.uptimeMillis();
11826        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11827
11828        for (int i=list.size()-1; i>=0; i--) {
11829            ProcessRecord r = list.get(i).first;
11830            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11831            char schedGroup;
11832            switch (r.setSchedGroup) {
11833                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11834                    schedGroup = 'B';
11835                    break;
11836                case Process.THREAD_GROUP_DEFAULT:
11837                    schedGroup = 'F';
11838                    break;
11839                default:
11840                    schedGroup = '?';
11841                    break;
11842            }
11843            char foreground;
11844            if (r.foregroundActivities) {
11845                foreground = 'A';
11846            } else if (r.foregroundServices) {
11847                foreground = 'S';
11848            } else {
11849                foreground = ' ';
11850            }
11851            String procState = ProcessList.makeProcStateString(r.curProcState);
11852            pw.print(prefix);
11853            pw.print(r.persistent ? persistentLabel : normalLabel);
11854            pw.print(" #");
11855            int num = (origList.size()-1)-list.get(i).second;
11856            if (num < 10) pw.print(' ');
11857            pw.print(num);
11858            pw.print(": ");
11859            pw.print(oomAdj);
11860            pw.print(' ');
11861            pw.print(schedGroup);
11862            pw.print('/');
11863            pw.print(foreground);
11864            pw.print('/');
11865            pw.print(procState);
11866            pw.print(" trm:");
11867            if (r.trimMemoryLevel < 10) pw.print(' ');
11868            pw.print(r.trimMemoryLevel);
11869            pw.print(' ');
11870            pw.print(r.toShortString());
11871            pw.print(" (");
11872            pw.print(r.adjType);
11873            pw.println(')');
11874            if (r.adjSource != null || r.adjTarget != null) {
11875                pw.print(prefix);
11876                pw.print("    ");
11877                if (r.adjTarget instanceof ComponentName) {
11878                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11879                } else if (r.adjTarget != null) {
11880                    pw.print(r.adjTarget.toString());
11881                } else {
11882                    pw.print("{null}");
11883                }
11884                pw.print("<=");
11885                if (r.adjSource instanceof ProcessRecord) {
11886                    pw.print("Proc{");
11887                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11888                    pw.println("}");
11889                } else if (r.adjSource != null) {
11890                    pw.println(r.adjSource.toString());
11891                } else {
11892                    pw.println("{null}");
11893                }
11894            }
11895            if (inclDetails) {
11896                pw.print(prefix);
11897                pw.print("    ");
11898                pw.print("oom: max="); pw.print(r.maxAdj);
11899                pw.print(" curRaw="); pw.print(r.curRawAdj);
11900                pw.print(" setRaw="); pw.print(r.setRawAdj);
11901                pw.print(" cur="); pw.print(r.curAdj);
11902                pw.print(" set="); pw.println(r.setAdj);
11903                pw.print(prefix);
11904                pw.print("    ");
11905                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11906                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11907                pw.print(" lastPss="); pw.print(r.lastPss);
11908                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11909                pw.print(prefix);
11910                pw.print("    ");
11911                pw.print("keeping="); pw.print(r.keeping);
11912                pw.print(" cached="); pw.print(r.cached);
11913                pw.print(" empty="); pw.print(r.empty);
11914                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11915
11916                if (!r.keeping) {
11917                    if (r.lastWakeTime != 0) {
11918                        long wtime;
11919                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11920                        synchronized (stats) {
11921                            wtime = stats.getProcessWakeTime(r.info.uid,
11922                                    r.pid, curRealtime);
11923                        }
11924                        long timeUsed = wtime - r.lastWakeTime;
11925                        pw.print(prefix);
11926                        pw.print("    ");
11927                        pw.print("keep awake over ");
11928                        TimeUtils.formatDuration(realtimeSince, pw);
11929                        pw.print(" used ");
11930                        TimeUtils.formatDuration(timeUsed, pw);
11931                        pw.print(" (");
11932                        pw.print((timeUsed*100)/realtimeSince);
11933                        pw.println("%)");
11934                    }
11935                    if (r.lastCpuTime != 0) {
11936                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11937                        pw.print(prefix);
11938                        pw.print("    ");
11939                        pw.print("run cpu over ");
11940                        TimeUtils.formatDuration(uptimeSince, pw);
11941                        pw.print(" used ");
11942                        TimeUtils.formatDuration(timeUsed, pw);
11943                        pw.print(" (");
11944                        pw.print((timeUsed*100)/uptimeSince);
11945                        pw.println("%)");
11946                    }
11947                }
11948            }
11949        }
11950        return true;
11951    }
11952
11953    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11954        ArrayList<ProcessRecord> procs;
11955        synchronized (this) {
11956            if (args != null && args.length > start
11957                    && args[start].charAt(0) != '-') {
11958                procs = new ArrayList<ProcessRecord>();
11959                int pid = -1;
11960                try {
11961                    pid = Integer.parseInt(args[start]);
11962                } catch (NumberFormatException e) {
11963                }
11964                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11965                    ProcessRecord proc = mLruProcesses.get(i);
11966                    if (proc.pid == pid) {
11967                        procs.add(proc);
11968                    } else if (proc.processName.equals(args[start])) {
11969                        procs.add(proc);
11970                    }
11971                }
11972                if (procs.size() <= 0) {
11973                    return null;
11974                }
11975            } else {
11976                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11977            }
11978        }
11979        return procs;
11980    }
11981
11982    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11983            PrintWriter pw, String[] args) {
11984        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11985        if (procs == null) {
11986            pw.println("No process found for: " + args[0]);
11987            return;
11988        }
11989
11990        long uptime = SystemClock.uptimeMillis();
11991        long realtime = SystemClock.elapsedRealtime();
11992        pw.println("Applications Graphics Acceleration Info:");
11993        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11994
11995        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11996            ProcessRecord r = procs.get(i);
11997            if (r.thread != null) {
11998                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11999                pw.flush();
12000                try {
12001                    TransferPipe tp = new TransferPipe();
12002                    try {
12003                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12004                        tp.go(fd);
12005                    } finally {
12006                        tp.kill();
12007                    }
12008                } catch (IOException e) {
12009                    pw.println("Failure while dumping the app: " + r);
12010                    pw.flush();
12011                } catch (RemoteException e) {
12012                    pw.println("Got a RemoteException while dumping the app " + r);
12013                    pw.flush();
12014                }
12015            }
12016        }
12017    }
12018
12019    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12020        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12021        if (procs == null) {
12022            pw.println("No process found for: " + args[0]);
12023            return;
12024        }
12025
12026        pw.println("Applications Database Info:");
12027
12028        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12029            ProcessRecord r = procs.get(i);
12030            if (r.thread != null) {
12031                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12032                pw.flush();
12033                try {
12034                    TransferPipe tp = new TransferPipe();
12035                    try {
12036                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12037                        tp.go(fd);
12038                    } finally {
12039                        tp.kill();
12040                    }
12041                } catch (IOException e) {
12042                    pw.println("Failure while dumping the app: " + r);
12043                    pw.flush();
12044                } catch (RemoteException e) {
12045                    pw.println("Got a RemoteException while dumping the app " + r);
12046                    pw.flush();
12047                }
12048            }
12049        }
12050    }
12051
12052    final static class MemItem {
12053        final boolean isProc;
12054        final String label;
12055        final String shortLabel;
12056        final long pss;
12057        final int id;
12058        final boolean hasActivities;
12059        ArrayList<MemItem> subitems;
12060
12061        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12062                boolean _hasActivities) {
12063            isProc = true;
12064            label = _label;
12065            shortLabel = _shortLabel;
12066            pss = _pss;
12067            id = _id;
12068            hasActivities = _hasActivities;
12069        }
12070
12071        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12072            isProc = false;
12073            label = _label;
12074            shortLabel = _shortLabel;
12075            pss = _pss;
12076            id = _id;
12077            hasActivities = false;
12078        }
12079    }
12080
12081    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12082            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12083        if (sort && !isCompact) {
12084            Collections.sort(items, new Comparator<MemItem>() {
12085                @Override
12086                public int compare(MemItem lhs, MemItem rhs) {
12087                    if (lhs.pss < rhs.pss) {
12088                        return 1;
12089                    } else if (lhs.pss > rhs.pss) {
12090                        return -1;
12091                    }
12092                    return 0;
12093                }
12094            });
12095        }
12096
12097        for (int i=0; i<items.size(); i++) {
12098            MemItem mi = items.get(i);
12099            if (!isCompact) {
12100                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12101            } else if (mi.isProc) {
12102                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12103                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12104                pw.println(mi.hasActivities ? ",a" : ",e");
12105            } else {
12106                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12107                pw.println(mi.pss);
12108            }
12109            if (mi.subitems != null) {
12110                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12111                        true, isCompact);
12112            }
12113        }
12114    }
12115
12116    // These are in KB.
12117    static final long[] DUMP_MEM_BUCKETS = new long[] {
12118        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12119        120*1024, 160*1024, 200*1024,
12120        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12121        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12122    };
12123
12124    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12125            boolean stackLike) {
12126        int start = label.lastIndexOf('.');
12127        if (start >= 0) start++;
12128        else start = 0;
12129        int end = label.length();
12130        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12131            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12132                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12133                out.append(bucket);
12134                out.append(stackLike ? "MB." : "MB ");
12135                out.append(label, start, end);
12136                return;
12137            }
12138        }
12139        out.append(memKB/1024);
12140        out.append(stackLike ? "MB." : "MB ");
12141        out.append(label, start, end);
12142    }
12143
12144    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12145            ProcessList.NATIVE_ADJ,
12146            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12147            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12148            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12149            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12150            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12151    };
12152    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12153            "Native",
12154            "System", "Persistent", "Foreground",
12155            "Visible", "Perceptible",
12156            "Heavy Weight", "Backup",
12157            "A Services", "Home",
12158            "Previous", "B Services", "Cached"
12159    };
12160    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12161            "native",
12162            "sys", "pers", "fore",
12163            "vis", "percept",
12164            "heavy", "backup",
12165            "servicea", "home",
12166            "prev", "serviceb", "cached"
12167    };
12168
12169    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12170            long realtime, boolean isCheckinRequest, boolean isCompact) {
12171        if (isCheckinRequest || isCompact) {
12172            // short checkin version
12173            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12174        } else {
12175            pw.println("Applications Memory Usage (kB):");
12176            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12177        }
12178    }
12179
12180    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12181            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12182        boolean dumpDetails = false;
12183        boolean dumpFullDetails = false;
12184        boolean dumpDalvik = false;
12185        boolean oomOnly = false;
12186        boolean isCompact = false;
12187        boolean localOnly = false;
12188
12189        int opti = 0;
12190        while (opti < args.length) {
12191            String opt = args[opti];
12192            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12193                break;
12194            }
12195            opti++;
12196            if ("-a".equals(opt)) {
12197                dumpDetails = true;
12198                dumpFullDetails = true;
12199                dumpDalvik = true;
12200            } else if ("-d".equals(opt)) {
12201                dumpDalvik = true;
12202            } else if ("-c".equals(opt)) {
12203                isCompact = true;
12204            } else if ("--oom".equals(opt)) {
12205                oomOnly = true;
12206            } else if ("--local".equals(opt)) {
12207                localOnly = true;
12208            } else if ("-h".equals(opt)) {
12209                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12210                pw.println("  -a: include all available information for each process.");
12211                pw.println("  -d: include dalvik details when dumping process details.");
12212                pw.println("  -c: dump in a compact machine-parseable representation.");
12213                pw.println("  --oom: only show processes organized by oom adj.");
12214                pw.println("  --local: only collect details locally, don't call process.");
12215                pw.println("If [process] is specified it can be the name or ");
12216                pw.println("pid of a specific process to dump.");
12217                return;
12218            } else {
12219                pw.println("Unknown argument: " + opt + "; use -h for help");
12220            }
12221        }
12222
12223        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12224        long uptime = SystemClock.uptimeMillis();
12225        long realtime = SystemClock.elapsedRealtime();
12226        final long[] tmpLong = new long[1];
12227
12228        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12229        if (procs == null) {
12230            // No Java processes.  Maybe they want to print a native process.
12231            if (args != null && args.length > opti
12232                    && args[opti].charAt(0) != '-') {
12233                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12234                        = new ArrayList<ProcessCpuTracker.Stats>();
12235                updateCpuStatsNow();
12236                int findPid = -1;
12237                try {
12238                    findPid = Integer.parseInt(args[opti]);
12239                } catch (NumberFormatException e) {
12240                }
12241                synchronized (mProcessCpuThread) {
12242                    final int N = mProcessCpuTracker.countStats();
12243                    for (int i=0; i<N; i++) {
12244                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12245                        if (st.pid == findPid || (st.baseName != null
12246                                && st.baseName.equals(args[opti]))) {
12247                            nativeProcs.add(st);
12248                        }
12249                    }
12250                }
12251                if (nativeProcs.size() > 0) {
12252                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12253                            isCompact);
12254                    Debug.MemoryInfo mi = null;
12255                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12256                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12257                        final int pid = r.pid;
12258                        if (!isCheckinRequest && dumpDetails) {
12259                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12260                        }
12261                        if (mi == null) {
12262                            mi = new Debug.MemoryInfo();
12263                        }
12264                        if (dumpDetails || (!brief && !oomOnly)) {
12265                            Debug.getMemoryInfo(pid, mi);
12266                        } else {
12267                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12268                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12269                        }
12270                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12271                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12272                        if (isCheckinRequest) {
12273                            pw.println();
12274                        }
12275                    }
12276                    return;
12277                }
12278            }
12279            pw.println("No process found for: " + args[opti]);
12280            return;
12281        }
12282
12283        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12284            dumpDetails = true;
12285        }
12286
12287        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12288
12289        String[] innerArgs = new String[args.length-opti];
12290        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12291
12292        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12293        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12294        long nativePss=0, dalvikPss=0, otherPss=0;
12295        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12296
12297        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12298        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12299                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12300
12301        long totalPss = 0;
12302        long cachedPss = 0;
12303
12304        Debug.MemoryInfo mi = null;
12305        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12306            final ProcessRecord r = procs.get(i);
12307            final IApplicationThread thread;
12308            final int pid;
12309            final int oomAdj;
12310            final boolean hasActivities;
12311            synchronized (this) {
12312                thread = r.thread;
12313                pid = r.pid;
12314                oomAdj = r.getSetAdjWithServices();
12315                hasActivities = r.activities.size() > 0;
12316            }
12317            if (thread != null) {
12318                if (!isCheckinRequest && dumpDetails) {
12319                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12320                }
12321                if (mi == null) {
12322                    mi = new Debug.MemoryInfo();
12323                }
12324                if (dumpDetails || (!brief && !oomOnly)) {
12325                    Debug.getMemoryInfo(pid, mi);
12326                } else {
12327                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12328                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12329                }
12330                if (dumpDetails) {
12331                    if (localOnly) {
12332                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12333                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12334                        if (isCheckinRequest) {
12335                            pw.println();
12336                        }
12337                    } else {
12338                        try {
12339                            pw.flush();
12340                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12341                                    dumpDalvik, innerArgs);
12342                        } catch (RemoteException e) {
12343                            if (!isCheckinRequest) {
12344                                pw.println("Got RemoteException!");
12345                                pw.flush();
12346                            }
12347                        }
12348                    }
12349                }
12350
12351                final long myTotalPss = mi.getTotalPss();
12352                final long myTotalUss = mi.getTotalUss();
12353
12354                synchronized (this) {
12355                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12356                        // Record this for posterity if the process has been stable.
12357                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12358                    }
12359                }
12360
12361                if (!isCheckinRequest && mi != null) {
12362                    totalPss += myTotalPss;
12363                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12364                            (hasActivities ? " / activities)" : ")"),
12365                            r.processName, myTotalPss, pid, hasActivities);
12366                    procMems.add(pssItem);
12367                    procMemsMap.put(pid, pssItem);
12368
12369                    nativePss += mi.nativePss;
12370                    dalvikPss += mi.dalvikPss;
12371                    otherPss += mi.otherPss;
12372                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12373                        long mem = mi.getOtherPss(j);
12374                        miscPss[j] += mem;
12375                        otherPss -= mem;
12376                    }
12377
12378                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12379                        cachedPss += myTotalPss;
12380                    }
12381
12382                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12383                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12384                                || oomIndex == (oomPss.length-1)) {
12385                            oomPss[oomIndex] += myTotalPss;
12386                            if (oomProcs[oomIndex] == null) {
12387                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12388                            }
12389                            oomProcs[oomIndex].add(pssItem);
12390                            break;
12391                        }
12392                    }
12393                }
12394            }
12395        }
12396
12397        if (!isCheckinRequest && procs.size() > 1) {
12398            // If we are showing aggregations, also look for native processes to
12399            // include so that our aggregations are more accurate.
12400            updateCpuStatsNow();
12401            synchronized (mProcessCpuThread) {
12402                final int N = mProcessCpuTracker.countStats();
12403                for (int i=0; i<N; i++) {
12404                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12405                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12406                        if (mi == null) {
12407                            mi = new Debug.MemoryInfo();
12408                        }
12409                        if (!brief && !oomOnly) {
12410                            Debug.getMemoryInfo(st.pid, mi);
12411                        } else {
12412                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12413                            mi.nativePrivateDirty = (int)tmpLong[0];
12414                        }
12415
12416                        final long myTotalPss = mi.getTotalPss();
12417                        totalPss += myTotalPss;
12418
12419                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12420                                st.name, myTotalPss, st.pid, false);
12421                        procMems.add(pssItem);
12422
12423                        nativePss += mi.nativePss;
12424                        dalvikPss += mi.dalvikPss;
12425                        otherPss += mi.otherPss;
12426                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12427                            long mem = mi.getOtherPss(j);
12428                            miscPss[j] += mem;
12429                            otherPss -= mem;
12430                        }
12431                        oomPss[0] += myTotalPss;
12432                        if (oomProcs[0] == null) {
12433                            oomProcs[0] = new ArrayList<MemItem>();
12434                        }
12435                        oomProcs[0].add(pssItem);
12436                    }
12437                }
12438            }
12439
12440            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12441
12442            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12443            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12444            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12445            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12446                String label = Debug.MemoryInfo.getOtherLabel(j);
12447                catMems.add(new MemItem(label, label, miscPss[j], j));
12448            }
12449
12450            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12451            for (int j=0; j<oomPss.length; j++) {
12452                if (oomPss[j] != 0) {
12453                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12454                            : DUMP_MEM_OOM_LABEL[j];
12455                    MemItem item = new MemItem(label, label, oomPss[j],
12456                            DUMP_MEM_OOM_ADJ[j]);
12457                    item.subitems = oomProcs[j];
12458                    oomMems.add(item);
12459                }
12460            }
12461
12462            if (!brief && !oomOnly && !isCompact) {
12463                pw.println();
12464                pw.println("Total PSS by process:");
12465                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12466                pw.println();
12467            }
12468            if (!isCompact) {
12469                pw.println("Total PSS by OOM adjustment:");
12470            }
12471            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12472            if (!brief && !oomOnly) {
12473                PrintWriter out = categoryPw != null ? categoryPw : pw;
12474                if (!isCompact) {
12475                    out.println();
12476                    out.println("Total PSS by category:");
12477                }
12478                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12479            }
12480            if (!isCompact) {
12481                pw.println();
12482            }
12483            MemInfoReader memInfo = new MemInfoReader();
12484            memInfo.readMemInfo();
12485            if (!brief) {
12486                if (!isCompact) {
12487                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12488                    pw.print(" kB (status ");
12489                    switch (mLastMemoryLevel) {
12490                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12491                            pw.println("normal)");
12492                            break;
12493                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12494                            pw.println("moderate)");
12495                            break;
12496                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12497                            pw.println("low)");
12498                            break;
12499                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12500                            pw.println("critical)");
12501                            break;
12502                        default:
12503                            pw.print(mLastMemoryLevel);
12504                            pw.println(")");
12505                            break;
12506                    }
12507                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12508                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12509                            pw.print(cachedPss); pw.print(" cached pss + ");
12510                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12511                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12512                } else {
12513                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12514                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12515                            + memInfo.getFreeSizeKb()); pw.print(",");
12516                    pw.println(totalPss - cachedPss);
12517                }
12518            }
12519            if (!isCompact) {
12520                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12521                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12522                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12523                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12524                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12525                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12526                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12527                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12528                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12529                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12530                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12531            }
12532            if (!brief) {
12533                if (memInfo.getZramTotalSizeKb() != 0) {
12534                    if (!isCompact) {
12535                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12536                                pw.print(" kB physical used for ");
12537                                pw.print(memInfo.getSwapTotalSizeKb()
12538                                        - memInfo.getSwapFreeSizeKb());
12539                                pw.print(" kB in swap (");
12540                                pw.print(memInfo.getSwapTotalSizeKb());
12541                                pw.println(" kB total swap)");
12542                    } else {
12543                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12544                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12545                                pw.println(memInfo.getSwapFreeSizeKb());
12546                    }
12547                }
12548                final int[] SINGLE_LONG_FORMAT = new int[] {
12549                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12550                };
12551                long[] longOut = new long[1];
12552                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12553                        SINGLE_LONG_FORMAT, null, longOut, null);
12554                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12555                longOut[0] = 0;
12556                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12557                        SINGLE_LONG_FORMAT, null, longOut, null);
12558                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12559                longOut[0] = 0;
12560                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12561                        SINGLE_LONG_FORMAT, null, longOut, null);
12562                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12563                longOut[0] = 0;
12564                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12565                        SINGLE_LONG_FORMAT, null, longOut, null);
12566                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12567                if (!isCompact) {
12568                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12569                        pw.print("      KSM: "); pw.print(sharing);
12570                                pw.print(" kB saved from shared ");
12571                                pw.print(shared); pw.println(" kB");
12572                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12573                                pw.print(voltile); pw.println(" kB volatile");
12574                    }
12575                    pw.print("   Tuning: ");
12576                    pw.print(ActivityManager.staticGetMemoryClass());
12577                    pw.print(" (large ");
12578                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12579                    pw.print("), oom ");
12580                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12581                    pw.print(" kB");
12582                    pw.print(", restore limit ");
12583                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12584                    pw.print(" kB");
12585                    if (ActivityManager.isLowRamDeviceStatic()) {
12586                        pw.print(" (low-ram)");
12587                    }
12588                    if (ActivityManager.isHighEndGfx()) {
12589                        pw.print(" (high-end-gfx)");
12590                    }
12591                    pw.println();
12592                } else {
12593                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12594                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12595                    pw.println(voltile);
12596                    pw.print("tuning,");
12597                    pw.print(ActivityManager.staticGetMemoryClass());
12598                    pw.print(',');
12599                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12600                    pw.print(',');
12601                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12602                    if (ActivityManager.isLowRamDeviceStatic()) {
12603                        pw.print(",low-ram");
12604                    }
12605                    if (ActivityManager.isHighEndGfx()) {
12606                        pw.print(",high-end-gfx");
12607                    }
12608                    pw.println();
12609                }
12610            }
12611        }
12612    }
12613
12614    /**
12615     * Searches array of arguments for the specified string
12616     * @param args array of argument strings
12617     * @param value value to search for
12618     * @return true if the value is contained in the array
12619     */
12620    private static boolean scanArgs(String[] args, String value) {
12621        if (args != null) {
12622            for (String arg : args) {
12623                if (value.equals(arg)) {
12624                    return true;
12625                }
12626            }
12627        }
12628        return false;
12629    }
12630
12631    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12632            ContentProviderRecord cpr, boolean always) {
12633        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12634
12635        if (!inLaunching || always) {
12636            synchronized (cpr) {
12637                cpr.launchingApp = null;
12638                cpr.notifyAll();
12639            }
12640            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12641            String names[] = cpr.info.authority.split(";");
12642            for (int j = 0; j < names.length; j++) {
12643                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12644            }
12645        }
12646
12647        for (int i=0; i<cpr.connections.size(); i++) {
12648            ContentProviderConnection conn = cpr.connections.get(i);
12649            if (conn.waiting) {
12650                // If this connection is waiting for the provider, then we don't
12651                // need to mess with its process unless we are always removing
12652                // or for some reason the provider is not currently launching.
12653                if (inLaunching && !always) {
12654                    continue;
12655                }
12656            }
12657            ProcessRecord capp = conn.client;
12658            conn.dead = true;
12659            if (conn.stableCount > 0) {
12660                if (!capp.persistent && capp.thread != null
12661                        && capp.pid != 0
12662                        && capp.pid != MY_PID) {
12663                    killUnneededProcessLocked(capp, "depends on provider "
12664                            + cpr.name.flattenToShortString()
12665                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12666                }
12667            } else if (capp.thread != null && conn.provider.provider != null) {
12668                try {
12669                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12670                } catch (RemoteException e) {
12671                }
12672                // In the protocol here, we don't expect the client to correctly
12673                // clean up this connection, we'll just remove it.
12674                cpr.connections.remove(i);
12675                conn.client.conProviders.remove(conn);
12676            }
12677        }
12678
12679        if (inLaunching && always) {
12680            mLaunchingProviders.remove(cpr);
12681        }
12682        return inLaunching;
12683    }
12684
12685    /**
12686     * Main code for cleaning up a process when it has gone away.  This is
12687     * called both as a result of the process dying, or directly when stopping
12688     * a process when running in single process mode.
12689     */
12690    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12691            boolean restarting, boolean allowRestart, int index) {
12692        if (index >= 0) {
12693            removeLruProcessLocked(app);
12694            ProcessList.remove(app.pid);
12695        }
12696
12697        mProcessesToGc.remove(app);
12698        mPendingPssProcesses.remove(app);
12699
12700        // Dismiss any open dialogs.
12701        if (app.crashDialog != null && !app.forceCrashReport) {
12702            app.crashDialog.dismiss();
12703            app.crashDialog = null;
12704        }
12705        if (app.anrDialog != null) {
12706            app.anrDialog.dismiss();
12707            app.anrDialog = null;
12708        }
12709        if (app.waitDialog != null) {
12710            app.waitDialog.dismiss();
12711            app.waitDialog = null;
12712        }
12713
12714        app.crashing = false;
12715        app.notResponding = false;
12716
12717        app.resetPackageList(mProcessStats);
12718        app.unlinkDeathRecipient();
12719        app.makeInactive(mProcessStats);
12720        app.forcingToForeground = null;
12721        updateProcessForegroundLocked(app, false, false);
12722        app.foregroundActivities = false;
12723        app.hasShownUi = false;
12724        app.treatLikeActivity = false;
12725        app.hasAboveClient = false;
12726        app.hasClientActivities = false;
12727
12728        mServices.killServicesLocked(app, allowRestart);
12729
12730        boolean restart = false;
12731
12732        // Remove published content providers.
12733        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12734            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12735            final boolean always = app.bad || !allowRestart;
12736            if (removeDyingProviderLocked(app, cpr, always) || always) {
12737                // We left the provider in the launching list, need to
12738                // restart it.
12739                restart = true;
12740            }
12741
12742            cpr.provider = null;
12743            cpr.proc = null;
12744        }
12745        app.pubProviders.clear();
12746
12747        // Take care of any launching providers waiting for this process.
12748        if (checkAppInLaunchingProvidersLocked(app, false)) {
12749            restart = true;
12750        }
12751
12752        // Unregister from connected content providers.
12753        if (!app.conProviders.isEmpty()) {
12754            for (int i=0; i<app.conProviders.size(); i++) {
12755                ContentProviderConnection conn = app.conProviders.get(i);
12756                conn.provider.connections.remove(conn);
12757            }
12758            app.conProviders.clear();
12759        }
12760
12761        // At this point there may be remaining entries in mLaunchingProviders
12762        // where we were the only one waiting, so they are no longer of use.
12763        // Look for these and clean up if found.
12764        // XXX Commented out for now.  Trying to figure out a way to reproduce
12765        // the actual situation to identify what is actually going on.
12766        if (false) {
12767            for (int i=0; i<mLaunchingProviders.size(); i++) {
12768                ContentProviderRecord cpr = (ContentProviderRecord)
12769                        mLaunchingProviders.get(i);
12770                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12771                    synchronized (cpr) {
12772                        cpr.launchingApp = null;
12773                        cpr.notifyAll();
12774                    }
12775                }
12776            }
12777        }
12778
12779        skipCurrentReceiverLocked(app);
12780
12781        // Unregister any receivers.
12782        for (int i=app.receivers.size()-1; i>=0; i--) {
12783            removeReceiverLocked(app.receivers.valueAt(i));
12784        }
12785        app.receivers.clear();
12786
12787        // If the app is undergoing backup, tell the backup manager about it
12788        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12789            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12790                    + mBackupTarget.appInfo + " died during backup");
12791            try {
12792                IBackupManager bm = IBackupManager.Stub.asInterface(
12793                        ServiceManager.getService(Context.BACKUP_SERVICE));
12794                bm.agentDisconnected(app.info.packageName);
12795            } catch (RemoteException e) {
12796                // can't happen; backup manager is local
12797            }
12798        }
12799
12800        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12801            ProcessChangeItem item = mPendingProcessChanges.get(i);
12802            if (item.pid == app.pid) {
12803                mPendingProcessChanges.remove(i);
12804                mAvailProcessChanges.add(item);
12805            }
12806        }
12807        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12808
12809        // If the caller is restarting this app, then leave it in its
12810        // current lists and let the caller take care of it.
12811        if (restarting) {
12812            return;
12813        }
12814
12815        if (!app.persistent || app.isolated) {
12816            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12817                    "Removing non-persistent process during cleanup: " + app);
12818            mProcessNames.remove(app.processName, app.uid);
12819            mIsolatedProcesses.remove(app.uid);
12820            if (mHeavyWeightProcess == app) {
12821                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12822                        mHeavyWeightProcess.userId, 0));
12823                mHeavyWeightProcess = null;
12824            }
12825        } else if (!app.removed) {
12826            // This app is persistent, so we need to keep its record around.
12827            // If it is not already on the pending app list, add it there
12828            // and start a new process for it.
12829            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12830                mPersistentStartingProcesses.add(app);
12831                restart = true;
12832            }
12833        }
12834        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12835                "Clean-up removing on hold: " + app);
12836        mProcessesOnHold.remove(app);
12837
12838        if (app == mHomeProcess) {
12839            mHomeProcess = null;
12840        }
12841        if (app == mPreviousProcess) {
12842            mPreviousProcess = null;
12843        }
12844
12845        if (restart && !app.isolated) {
12846            // We have components that still need to be running in the
12847            // process, so re-launch it.
12848            mProcessNames.put(app.processName, app.uid, app);
12849            startProcessLocked(app, "restart", app.processName);
12850        } else if (app.pid > 0 && app.pid != MY_PID) {
12851            // Goodbye!
12852            boolean removed;
12853            synchronized (mPidsSelfLocked) {
12854                mPidsSelfLocked.remove(app.pid);
12855                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12856            }
12857            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12858                    app.processName, app.info.uid);
12859            if (app.isolated) {
12860                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12861            }
12862            app.setPid(0);
12863        }
12864    }
12865
12866    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12867        // Look through the content providers we are waiting to have launched,
12868        // and if any run in this process then either schedule a restart of
12869        // the process or kill the client waiting for it if this process has
12870        // gone bad.
12871        int NL = mLaunchingProviders.size();
12872        boolean restart = false;
12873        for (int i=0; i<NL; i++) {
12874            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12875            if (cpr.launchingApp == app) {
12876                if (!alwaysBad && !app.bad) {
12877                    restart = true;
12878                } else {
12879                    removeDyingProviderLocked(app, cpr, true);
12880                    // cpr should have been removed from mLaunchingProviders
12881                    NL = mLaunchingProviders.size();
12882                    i--;
12883                }
12884            }
12885        }
12886        return restart;
12887    }
12888
12889    // =========================================================
12890    // SERVICES
12891    // =========================================================
12892
12893    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12894            int flags) {
12895        enforceNotIsolatedCaller("getServices");
12896        synchronized (this) {
12897            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12898        }
12899    }
12900
12901    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12902        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12903        synchronized (this) {
12904            return mServices.getRunningServiceControlPanelLocked(name);
12905        }
12906    }
12907
12908    public ComponentName startService(IApplicationThread caller, Intent service,
12909            String resolvedType, int userId) {
12910        enforceNotIsolatedCaller("startService");
12911        // Refuse possible leaked file descriptors
12912        if (service != null && service.hasFileDescriptors() == true) {
12913            throw new IllegalArgumentException("File descriptors passed in Intent");
12914        }
12915
12916        if (DEBUG_SERVICE)
12917            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12918        synchronized(this) {
12919            final int callingPid = Binder.getCallingPid();
12920            final int callingUid = Binder.getCallingUid();
12921            final long origId = Binder.clearCallingIdentity();
12922            ComponentName res = mServices.startServiceLocked(caller, service,
12923                    resolvedType, callingPid, callingUid, userId);
12924            Binder.restoreCallingIdentity(origId);
12925            return res;
12926        }
12927    }
12928
12929    ComponentName startServiceInPackage(int uid,
12930            Intent service, String resolvedType, int userId) {
12931        synchronized(this) {
12932            if (DEBUG_SERVICE)
12933                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12934            final long origId = Binder.clearCallingIdentity();
12935            ComponentName res = mServices.startServiceLocked(null, service,
12936                    resolvedType, -1, uid, userId);
12937            Binder.restoreCallingIdentity(origId);
12938            return res;
12939        }
12940    }
12941
12942    public int stopService(IApplicationThread caller, Intent service,
12943            String resolvedType, int userId) {
12944        enforceNotIsolatedCaller("stopService");
12945        // Refuse possible leaked file descriptors
12946        if (service != null && service.hasFileDescriptors() == true) {
12947            throw new IllegalArgumentException("File descriptors passed in Intent");
12948        }
12949
12950        synchronized(this) {
12951            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12952        }
12953    }
12954
12955    public IBinder peekService(Intent service, String resolvedType) {
12956        enforceNotIsolatedCaller("peekService");
12957        // Refuse possible leaked file descriptors
12958        if (service != null && service.hasFileDescriptors() == true) {
12959            throw new IllegalArgumentException("File descriptors passed in Intent");
12960        }
12961        synchronized(this) {
12962            return mServices.peekServiceLocked(service, resolvedType);
12963        }
12964    }
12965
12966    public boolean stopServiceToken(ComponentName className, IBinder token,
12967            int startId) {
12968        synchronized(this) {
12969            return mServices.stopServiceTokenLocked(className, token, startId);
12970        }
12971    }
12972
12973    public void setServiceForeground(ComponentName className, IBinder token,
12974            int id, Notification notification, boolean removeNotification) {
12975        synchronized(this) {
12976            mServices.setServiceForegroundLocked(className, token, id, notification,
12977                    removeNotification);
12978        }
12979    }
12980
12981    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12982            boolean requireFull, String name, String callerPackage) {
12983        final int callingUserId = UserHandle.getUserId(callingUid);
12984        if (callingUserId != userId) {
12985            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12986                if ((requireFull || checkComponentPermission(
12987                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12988                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12989                        && checkComponentPermission(
12990                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12991                                callingPid, callingUid, -1, true)
12992                                != PackageManager.PERMISSION_GRANTED) {
12993                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12994                        // In this case, they would like to just execute as their
12995                        // owner user instead of failing.
12996                        userId = callingUserId;
12997                    } else {
12998                        StringBuilder builder = new StringBuilder(128);
12999                        builder.append("Permission Denial: ");
13000                        builder.append(name);
13001                        if (callerPackage != null) {
13002                            builder.append(" from ");
13003                            builder.append(callerPackage);
13004                        }
13005                        builder.append(" asks to run as user ");
13006                        builder.append(userId);
13007                        builder.append(" but is calling from user ");
13008                        builder.append(UserHandle.getUserId(callingUid));
13009                        builder.append("; this requires ");
13010                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13011                        if (!requireFull) {
13012                            builder.append(" or ");
13013                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13014                        }
13015                        String msg = builder.toString();
13016                        Slog.w(TAG, msg);
13017                        throw new SecurityException(msg);
13018                    }
13019                }
13020            }
13021            if (userId == UserHandle.USER_CURRENT
13022                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13023                // Note that we may be accessing this outside of a lock...
13024                // shouldn't be a big deal, if this is being called outside
13025                // of a locked context there is intrinsically a race with
13026                // the value the caller will receive and someone else changing it.
13027                userId = mCurrentUserId;
13028            }
13029            if (!allowAll && userId < 0) {
13030                throw new IllegalArgumentException(
13031                        "Call does not support special user #" + userId);
13032            }
13033        }
13034        return userId;
13035    }
13036
13037    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13038            String className, int flags) {
13039        boolean result = false;
13040        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13041            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13042                if (ActivityManager.checkUidPermission(
13043                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13044                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13045                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13046                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13047                            + " requests FLAG_SINGLE_USER, but app does not hold "
13048                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13049                    Slog.w(TAG, msg);
13050                    throw new SecurityException(msg);
13051                }
13052                result = true;
13053            }
13054        } else if (componentProcessName == aInfo.packageName) {
13055            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13056        } else if ("system".equals(componentProcessName)) {
13057            result = true;
13058        }
13059        if (DEBUG_MU) {
13060            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13061                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13062        }
13063        return result;
13064    }
13065
13066    public int bindService(IApplicationThread caller, IBinder token,
13067            Intent service, String resolvedType,
13068            IServiceConnection connection, int flags, int userId) {
13069        enforceNotIsolatedCaller("bindService");
13070        // Refuse possible leaked file descriptors
13071        if (service != null && service.hasFileDescriptors() == true) {
13072            throw new IllegalArgumentException("File descriptors passed in Intent");
13073        }
13074
13075        synchronized(this) {
13076            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13077                    connection, flags, userId);
13078        }
13079    }
13080
13081    public boolean unbindService(IServiceConnection connection) {
13082        synchronized (this) {
13083            return mServices.unbindServiceLocked(connection);
13084        }
13085    }
13086
13087    public void publishService(IBinder token, Intent intent, IBinder service) {
13088        // Refuse possible leaked file descriptors
13089        if (intent != null && intent.hasFileDescriptors() == true) {
13090            throw new IllegalArgumentException("File descriptors passed in Intent");
13091        }
13092
13093        synchronized(this) {
13094            if (!(token instanceof ServiceRecord)) {
13095                throw new IllegalArgumentException("Invalid service token");
13096            }
13097            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13098        }
13099    }
13100
13101    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13102        // Refuse possible leaked file descriptors
13103        if (intent != null && intent.hasFileDescriptors() == true) {
13104            throw new IllegalArgumentException("File descriptors passed in Intent");
13105        }
13106
13107        synchronized(this) {
13108            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13109        }
13110    }
13111
13112    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13113        synchronized(this) {
13114            if (!(token instanceof ServiceRecord)) {
13115                throw new IllegalArgumentException("Invalid service token");
13116            }
13117            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13118        }
13119    }
13120
13121    // =========================================================
13122    // BACKUP AND RESTORE
13123    // =========================================================
13124
13125    // Cause the target app to be launched if necessary and its backup agent
13126    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13127    // activity manager to announce its creation.
13128    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13129        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13130        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13131
13132        synchronized(this) {
13133            // !!! TODO: currently no check here that we're already bound
13134            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13135            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13136            synchronized (stats) {
13137                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13138            }
13139
13140            // Backup agent is now in use, its package can't be stopped.
13141            try {
13142                AppGlobals.getPackageManager().setPackageStoppedState(
13143                        app.packageName, false, UserHandle.getUserId(app.uid));
13144            } catch (RemoteException e) {
13145            } catch (IllegalArgumentException e) {
13146                Slog.w(TAG, "Failed trying to unstop package "
13147                        + app.packageName + ": " + e);
13148            }
13149
13150            BackupRecord r = new BackupRecord(ss, app, backupMode);
13151            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13152                    ? new ComponentName(app.packageName, app.backupAgentName)
13153                    : new ComponentName("android", "FullBackupAgent");
13154            // startProcessLocked() returns existing proc's record if it's already running
13155            ProcessRecord proc = startProcessLocked(app.processName, app,
13156                    false, 0, "backup", hostingName, false, false, false);
13157            if (proc == null) {
13158                Slog.e(TAG, "Unable to start backup agent process " + r);
13159                return false;
13160            }
13161
13162            r.app = proc;
13163            mBackupTarget = r;
13164            mBackupAppName = app.packageName;
13165
13166            // Try not to kill the process during backup
13167            updateOomAdjLocked(proc);
13168
13169            // If the process is already attached, schedule the creation of the backup agent now.
13170            // If it is not yet live, this will be done when it attaches to the framework.
13171            if (proc.thread != null) {
13172                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13173                try {
13174                    proc.thread.scheduleCreateBackupAgent(app,
13175                            compatibilityInfoForPackageLocked(app), backupMode);
13176                } catch (RemoteException e) {
13177                    // Will time out on the backup manager side
13178                }
13179            } else {
13180                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13181            }
13182            // Invariants: at this point, the target app process exists and the application
13183            // is either already running or in the process of coming up.  mBackupTarget and
13184            // mBackupAppName describe the app, so that when it binds back to the AM we
13185            // know that it's scheduled for a backup-agent operation.
13186        }
13187
13188        return true;
13189    }
13190
13191    @Override
13192    public void clearPendingBackup() {
13193        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13194        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13195
13196        synchronized (this) {
13197            mBackupTarget = null;
13198            mBackupAppName = null;
13199        }
13200    }
13201
13202    // A backup agent has just come up
13203    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13204        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13205                + " = " + agent);
13206
13207        synchronized(this) {
13208            if (!agentPackageName.equals(mBackupAppName)) {
13209                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13210                return;
13211            }
13212        }
13213
13214        long oldIdent = Binder.clearCallingIdentity();
13215        try {
13216            IBackupManager bm = IBackupManager.Stub.asInterface(
13217                    ServiceManager.getService(Context.BACKUP_SERVICE));
13218            bm.agentConnected(agentPackageName, agent);
13219        } catch (RemoteException e) {
13220            // can't happen; the backup manager service is local
13221        } catch (Exception e) {
13222            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13223            e.printStackTrace();
13224        } finally {
13225            Binder.restoreCallingIdentity(oldIdent);
13226        }
13227    }
13228
13229    // done with this agent
13230    public void unbindBackupAgent(ApplicationInfo appInfo) {
13231        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13232        if (appInfo == null) {
13233            Slog.w(TAG, "unbind backup agent for null app");
13234            return;
13235        }
13236
13237        synchronized(this) {
13238            try {
13239                if (mBackupAppName == null) {
13240                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13241                    return;
13242                }
13243
13244                if (!mBackupAppName.equals(appInfo.packageName)) {
13245                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13246                    return;
13247                }
13248
13249                // Not backing this app up any more; reset its OOM adjustment
13250                final ProcessRecord proc = mBackupTarget.app;
13251                updateOomAdjLocked(proc);
13252
13253                // If the app crashed during backup, 'thread' will be null here
13254                if (proc.thread != null) {
13255                    try {
13256                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13257                                compatibilityInfoForPackageLocked(appInfo));
13258                    } catch (Exception e) {
13259                        Slog.e(TAG, "Exception when unbinding backup agent:");
13260                        e.printStackTrace();
13261                    }
13262                }
13263            } finally {
13264                mBackupTarget = null;
13265                mBackupAppName = null;
13266            }
13267        }
13268    }
13269    // =========================================================
13270    // BROADCASTS
13271    // =========================================================
13272
13273    private final List getStickiesLocked(String action, IntentFilter filter,
13274            List cur, int userId) {
13275        final ContentResolver resolver = mContext.getContentResolver();
13276        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13277        if (stickies == null) {
13278            return cur;
13279        }
13280        final ArrayList<Intent> list = stickies.get(action);
13281        if (list == null) {
13282            return cur;
13283        }
13284        int N = list.size();
13285        for (int i=0; i<N; i++) {
13286            Intent intent = list.get(i);
13287            if (filter.match(resolver, intent, true, TAG) >= 0) {
13288                if (cur == null) {
13289                    cur = new ArrayList<Intent>();
13290                }
13291                cur.add(intent);
13292            }
13293        }
13294        return cur;
13295    }
13296
13297    boolean isPendingBroadcastProcessLocked(int pid) {
13298        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13299                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13300    }
13301
13302    void skipPendingBroadcastLocked(int pid) {
13303            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13304            for (BroadcastQueue queue : mBroadcastQueues) {
13305                queue.skipPendingBroadcastLocked(pid);
13306            }
13307    }
13308
13309    // The app just attached; send any pending broadcasts that it should receive
13310    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13311        boolean didSomething = false;
13312        for (BroadcastQueue queue : mBroadcastQueues) {
13313            didSomething |= queue.sendPendingBroadcastsLocked(app);
13314        }
13315        return didSomething;
13316    }
13317
13318    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13319            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13320        enforceNotIsolatedCaller("registerReceiver");
13321        int callingUid;
13322        int callingPid;
13323        synchronized(this) {
13324            ProcessRecord callerApp = null;
13325            if (caller != null) {
13326                callerApp = getRecordForAppLocked(caller);
13327                if (callerApp == null) {
13328                    throw new SecurityException(
13329                            "Unable to find app for caller " + caller
13330                            + " (pid=" + Binder.getCallingPid()
13331                            + ") when registering receiver " + receiver);
13332                }
13333                if (callerApp.info.uid != Process.SYSTEM_UID &&
13334                        !callerApp.pkgList.containsKey(callerPackage) &&
13335                        !"android".equals(callerPackage)) {
13336                    throw new SecurityException("Given caller package " + callerPackage
13337                            + " is not running in process " + callerApp);
13338                }
13339                callingUid = callerApp.info.uid;
13340                callingPid = callerApp.pid;
13341            } else {
13342                callerPackage = null;
13343                callingUid = Binder.getCallingUid();
13344                callingPid = Binder.getCallingPid();
13345            }
13346
13347            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13348                    true, true, "registerReceiver", callerPackage);
13349
13350            List allSticky = null;
13351
13352            // Look for any matching sticky broadcasts...
13353            Iterator actions = filter.actionsIterator();
13354            if (actions != null) {
13355                while (actions.hasNext()) {
13356                    String action = (String)actions.next();
13357                    allSticky = getStickiesLocked(action, filter, allSticky,
13358                            UserHandle.USER_ALL);
13359                    allSticky = getStickiesLocked(action, filter, allSticky,
13360                            UserHandle.getUserId(callingUid));
13361                }
13362            } else {
13363                allSticky = getStickiesLocked(null, filter, allSticky,
13364                        UserHandle.USER_ALL);
13365                allSticky = getStickiesLocked(null, filter, allSticky,
13366                        UserHandle.getUserId(callingUid));
13367            }
13368
13369            // The first sticky in the list is returned directly back to
13370            // the client.
13371            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13372
13373            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13374                    + ": " + sticky);
13375
13376            if (receiver == null) {
13377                return sticky;
13378            }
13379
13380            ReceiverList rl
13381                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13382            if (rl == null) {
13383                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13384                        userId, receiver);
13385                if (rl.app != null) {
13386                    rl.app.receivers.add(rl);
13387                } else {
13388                    try {
13389                        receiver.asBinder().linkToDeath(rl, 0);
13390                    } catch (RemoteException e) {
13391                        return sticky;
13392                    }
13393                    rl.linkedToDeath = true;
13394                }
13395                mRegisteredReceivers.put(receiver.asBinder(), rl);
13396            } else if (rl.uid != callingUid) {
13397                throw new IllegalArgumentException(
13398                        "Receiver requested to register for uid " + callingUid
13399                        + " was previously registered for uid " + rl.uid);
13400            } else if (rl.pid != callingPid) {
13401                throw new IllegalArgumentException(
13402                        "Receiver requested to register for pid " + callingPid
13403                        + " was previously registered for pid " + rl.pid);
13404            } else if (rl.userId != userId) {
13405                throw new IllegalArgumentException(
13406                        "Receiver requested to register for user " + userId
13407                        + " was previously registered for user " + rl.userId);
13408            }
13409            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13410                    permission, callingUid, userId);
13411            rl.add(bf);
13412            if (!bf.debugCheck()) {
13413                Slog.w(TAG, "==> For Dynamic broadast");
13414            }
13415            mReceiverResolver.addFilter(bf);
13416
13417            // Enqueue broadcasts for all existing stickies that match
13418            // this filter.
13419            if (allSticky != null) {
13420                ArrayList receivers = new ArrayList();
13421                receivers.add(bf);
13422
13423                int N = allSticky.size();
13424                for (int i=0; i<N; i++) {
13425                    Intent intent = (Intent)allSticky.get(i);
13426                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13427                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13428                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13429                            null, null, false, true, true, -1);
13430                    queue.enqueueParallelBroadcastLocked(r);
13431                    queue.scheduleBroadcastsLocked();
13432                }
13433            }
13434
13435            return sticky;
13436        }
13437    }
13438
13439    public void unregisterReceiver(IIntentReceiver receiver) {
13440        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13441
13442        final long origId = Binder.clearCallingIdentity();
13443        try {
13444            boolean doTrim = false;
13445
13446            synchronized(this) {
13447                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13448                if (rl != null) {
13449                    if (rl.curBroadcast != null) {
13450                        BroadcastRecord r = rl.curBroadcast;
13451                        final boolean doNext = finishReceiverLocked(
13452                                receiver.asBinder(), r.resultCode, r.resultData,
13453                                r.resultExtras, r.resultAbort);
13454                        if (doNext) {
13455                            doTrim = true;
13456                            r.queue.processNextBroadcast(false);
13457                        }
13458                    }
13459
13460                    if (rl.app != null) {
13461                        rl.app.receivers.remove(rl);
13462                    }
13463                    removeReceiverLocked(rl);
13464                    if (rl.linkedToDeath) {
13465                        rl.linkedToDeath = false;
13466                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13467                    }
13468                }
13469            }
13470
13471            // If we actually concluded any broadcasts, we might now be able
13472            // to trim the recipients' apps from our working set
13473            if (doTrim) {
13474                trimApplications();
13475                return;
13476            }
13477
13478        } finally {
13479            Binder.restoreCallingIdentity(origId);
13480        }
13481    }
13482
13483    void removeReceiverLocked(ReceiverList rl) {
13484        mRegisteredReceivers.remove(rl.receiver.asBinder());
13485        int N = rl.size();
13486        for (int i=0; i<N; i++) {
13487            mReceiverResolver.removeFilter(rl.get(i));
13488        }
13489    }
13490
13491    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13492        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13493            ProcessRecord r = mLruProcesses.get(i);
13494            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13495                try {
13496                    r.thread.dispatchPackageBroadcast(cmd, packages);
13497                } catch (RemoteException ex) {
13498                }
13499            }
13500        }
13501    }
13502
13503    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13504            int[] users) {
13505        List<ResolveInfo> receivers = null;
13506        try {
13507            HashSet<ComponentName> singleUserReceivers = null;
13508            boolean scannedFirstReceivers = false;
13509            for (int user : users) {
13510                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13511                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13512                if (user != 0 && newReceivers != null) {
13513                    // If this is not the primary user, we need to check for
13514                    // any receivers that should be filtered out.
13515                    for (int i=0; i<newReceivers.size(); i++) {
13516                        ResolveInfo ri = newReceivers.get(i);
13517                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13518                            newReceivers.remove(i);
13519                            i--;
13520                        }
13521                    }
13522                }
13523                if (newReceivers != null && newReceivers.size() == 0) {
13524                    newReceivers = null;
13525                }
13526                if (receivers == null) {
13527                    receivers = newReceivers;
13528                } else if (newReceivers != null) {
13529                    // We need to concatenate the additional receivers
13530                    // found with what we have do far.  This would be easy,
13531                    // but we also need to de-dup any receivers that are
13532                    // singleUser.
13533                    if (!scannedFirstReceivers) {
13534                        // Collect any single user receivers we had already retrieved.
13535                        scannedFirstReceivers = true;
13536                        for (int i=0; i<receivers.size(); i++) {
13537                            ResolveInfo ri = receivers.get(i);
13538                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13539                                ComponentName cn = new ComponentName(
13540                                        ri.activityInfo.packageName, ri.activityInfo.name);
13541                                if (singleUserReceivers == null) {
13542                                    singleUserReceivers = new HashSet<ComponentName>();
13543                                }
13544                                singleUserReceivers.add(cn);
13545                            }
13546                        }
13547                    }
13548                    // Add the new results to the existing results, tracking
13549                    // and de-dupping single user receivers.
13550                    for (int i=0; i<newReceivers.size(); i++) {
13551                        ResolveInfo ri = newReceivers.get(i);
13552                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13553                            ComponentName cn = new ComponentName(
13554                                    ri.activityInfo.packageName, ri.activityInfo.name);
13555                            if (singleUserReceivers == null) {
13556                                singleUserReceivers = new HashSet<ComponentName>();
13557                            }
13558                            if (!singleUserReceivers.contains(cn)) {
13559                                singleUserReceivers.add(cn);
13560                                receivers.add(ri);
13561                            }
13562                        } else {
13563                            receivers.add(ri);
13564                        }
13565                    }
13566                }
13567            }
13568        } catch (RemoteException ex) {
13569            // pm is in same process, this will never happen.
13570        }
13571        return receivers;
13572    }
13573
13574    private final int broadcastIntentLocked(ProcessRecord callerApp,
13575            String callerPackage, Intent intent, String resolvedType,
13576            IIntentReceiver resultTo, int resultCode, String resultData,
13577            Bundle map, String requiredPermission, int appOp,
13578            boolean ordered, boolean sticky, int callingPid, int callingUid,
13579            int userId) {
13580        intent = new Intent(intent);
13581
13582        // By default broadcasts do not go to stopped apps.
13583        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13584
13585        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13586            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13587            + " ordered=" + ordered + " userid=" + userId);
13588        if ((resultTo != null) && !ordered) {
13589            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13590        }
13591
13592        userId = handleIncomingUser(callingPid, callingUid, userId,
13593                true, false, "broadcast", callerPackage);
13594
13595        // Make sure that the user who is receiving this broadcast is started.
13596        // If not, we will just skip it.
13597        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13598            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13599                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13600                Slog.w(TAG, "Skipping broadcast of " + intent
13601                        + ": user " + userId + " is stopped");
13602                return ActivityManager.BROADCAST_SUCCESS;
13603            }
13604        }
13605
13606        /*
13607         * Prevent non-system code (defined here to be non-persistent
13608         * processes) from sending protected broadcasts.
13609         */
13610        int callingAppId = UserHandle.getAppId(callingUid);
13611        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13612            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13613            callingUid == 0) {
13614            // Always okay.
13615        } else if (callerApp == null || !callerApp.persistent) {
13616            try {
13617                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13618                        intent.getAction())) {
13619                    String msg = "Permission Denial: not allowed to send broadcast "
13620                            + intent.getAction() + " from pid="
13621                            + callingPid + ", uid=" + callingUid;
13622                    Slog.w(TAG, msg);
13623                    throw new SecurityException(msg);
13624                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13625                    // Special case for compatibility: we don't want apps to send this,
13626                    // but historically it has not been protected and apps may be using it
13627                    // to poke their own app widget.  So, instead of making it protected,
13628                    // just limit it to the caller.
13629                    if (callerApp == null) {
13630                        String msg = "Permission Denial: not allowed to send broadcast "
13631                                + intent.getAction() + " from unknown caller.";
13632                        Slog.w(TAG, msg);
13633                        throw new SecurityException(msg);
13634                    } else if (intent.getComponent() != null) {
13635                        // They are good enough to send to an explicit component...  verify
13636                        // it is being sent to the calling app.
13637                        if (!intent.getComponent().getPackageName().equals(
13638                                callerApp.info.packageName)) {
13639                            String msg = "Permission Denial: not allowed to send broadcast "
13640                                    + intent.getAction() + " to "
13641                                    + intent.getComponent().getPackageName() + " from "
13642                                    + callerApp.info.packageName;
13643                            Slog.w(TAG, msg);
13644                            throw new SecurityException(msg);
13645                        }
13646                    } else {
13647                        // Limit broadcast to their own package.
13648                        intent.setPackage(callerApp.info.packageName);
13649                    }
13650                }
13651            } catch (RemoteException e) {
13652                Slog.w(TAG, "Remote exception", e);
13653                return ActivityManager.BROADCAST_SUCCESS;
13654            }
13655        }
13656
13657        // Handle special intents: if this broadcast is from the package
13658        // manager about a package being removed, we need to remove all of
13659        // its activities from the history stack.
13660        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13661                intent.getAction());
13662        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13663                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13664                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13665                || uidRemoved) {
13666            if (checkComponentPermission(
13667                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13668                    callingPid, callingUid, -1, true)
13669                    == PackageManager.PERMISSION_GRANTED) {
13670                if (uidRemoved) {
13671                    final Bundle intentExtras = intent.getExtras();
13672                    final int uid = intentExtras != null
13673                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13674                    if (uid >= 0) {
13675                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13676                        synchronized (bs) {
13677                            bs.removeUidStatsLocked(uid);
13678                        }
13679                        mAppOpsService.uidRemoved(uid);
13680                    }
13681                } else {
13682                    // If resources are unavailable just force stop all
13683                    // those packages and flush the attribute cache as well.
13684                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13685                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13686                        if (list != null && (list.length > 0)) {
13687                            for (String pkg : list) {
13688                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13689                                        "storage unmount");
13690                            }
13691                            sendPackageBroadcastLocked(
13692                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13693                        }
13694                    } else {
13695                        Uri data = intent.getData();
13696                        String ssp;
13697                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13698                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13699                                    intent.getAction());
13700                            boolean fullUninstall = removed &&
13701                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13702                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13703                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13704                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13705                                        false, fullUninstall, userId,
13706                                        removed ? "pkg removed" : "pkg changed");
13707                            }
13708                            if (removed) {
13709                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13710                                        new String[] {ssp}, userId);
13711                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13712                                    mAppOpsService.packageRemoved(
13713                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13714
13715                                    // Remove all permissions granted from/to this package
13716                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13717                                }
13718                            }
13719                        }
13720                    }
13721                }
13722            } else {
13723                String msg = "Permission Denial: " + intent.getAction()
13724                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13725                        + ", uid=" + callingUid + ")"
13726                        + " requires "
13727                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13728                Slog.w(TAG, msg);
13729                throw new SecurityException(msg);
13730            }
13731
13732        // Special case for adding a package: by default turn on compatibility
13733        // mode.
13734        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13735            Uri data = intent.getData();
13736            String ssp;
13737            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13738                mCompatModePackages.handlePackageAddedLocked(ssp,
13739                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13740            }
13741        }
13742
13743        /*
13744         * If this is the time zone changed action, queue up a message that will reset the timezone
13745         * of all currently running processes. This message will get queued up before the broadcast
13746         * happens.
13747         */
13748        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13749            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13750        }
13751
13752        /*
13753         * If the user set the time, let all running processes know.
13754         */
13755        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13756            final int is24Hour = intent.getBooleanExtra(
13757                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13758            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13759        }
13760
13761        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13762            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13763        }
13764
13765        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13766            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13767            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13768        }
13769
13770        // Add to the sticky list if requested.
13771        if (sticky) {
13772            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13773                    callingPid, callingUid)
13774                    != PackageManager.PERMISSION_GRANTED) {
13775                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13776                        + callingPid + ", uid=" + callingUid
13777                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13778                Slog.w(TAG, msg);
13779                throw new SecurityException(msg);
13780            }
13781            if (requiredPermission != null) {
13782                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13783                        + " and enforce permission " + requiredPermission);
13784                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13785            }
13786            if (intent.getComponent() != null) {
13787                throw new SecurityException(
13788                        "Sticky broadcasts can't target a specific component");
13789            }
13790            // We use userId directly here, since the "all" target is maintained
13791            // as a separate set of sticky broadcasts.
13792            if (userId != UserHandle.USER_ALL) {
13793                // But first, if this is not a broadcast to all users, then
13794                // make sure it doesn't conflict with an existing broadcast to
13795                // all users.
13796                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13797                        UserHandle.USER_ALL);
13798                if (stickies != null) {
13799                    ArrayList<Intent> list = stickies.get(intent.getAction());
13800                    if (list != null) {
13801                        int N = list.size();
13802                        int i;
13803                        for (i=0; i<N; i++) {
13804                            if (intent.filterEquals(list.get(i))) {
13805                                throw new IllegalArgumentException(
13806                                        "Sticky broadcast " + intent + " for user "
13807                                        + userId + " conflicts with existing global broadcast");
13808                            }
13809                        }
13810                    }
13811                }
13812            }
13813            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13814            if (stickies == null) {
13815                stickies = new ArrayMap<String, ArrayList<Intent>>();
13816                mStickyBroadcasts.put(userId, stickies);
13817            }
13818            ArrayList<Intent> list = stickies.get(intent.getAction());
13819            if (list == null) {
13820                list = new ArrayList<Intent>();
13821                stickies.put(intent.getAction(), list);
13822            }
13823            int N = list.size();
13824            int i;
13825            for (i=0; i<N; i++) {
13826                if (intent.filterEquals(list.get(i))) {
13827                    // This sticky already exists, replace it.
13828                    list.set(i, new Intent(intent));
13829                    break;
13830                }
13831            }
13832            if (i >= N) {
13833                list.add(new Intent(intent));
13834            }
13835        }
13836
13837        int[] users;
13838        if (userId == UserHandle.USER_ALL) {
13839            // Caller wants broadcast to go to all started users.
13840            users = mStartedUserArray;
13841        } else {
13842            // Caller wants broadcast to go to one specific user.
13843            users = new int[] {userId};
13844        }
13845
13846        // Figure out who all will receive this broadcast.
13847        List receivers = null;
13848        List<BroadcastFilter> registeredReceivers = null;
13849        // Need to resolve the intent to interested receivers...
13850        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13851                 == 0) {
13852            receivers = collectReceiverComponents(intent, resolvedType, users);
13853        }
13854        if (intent.getComponent() == null) {
13855            registeredReceivers = mReceiverResolver.queryIntent(intent,
13856                    resolvedType, false, userId);
13857        }
13858
13859        final boolean replacePending =
13860                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13861
13862        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13863                + " replacePending=" + replacePending);
13864
13865        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13866        if (!ordered && NR > 0) {
13867            // If we are not serializing this broadcast, then send the
13868            // registered receivers separately so they don't wait for the
13869            // components to be launched.
13870            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13871            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13872                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13873                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13874                    ordered, sticky, false, userId);
13875            if (DEBUG_BROADCAST) Slog.v(
13876                    TAG, "Enqueueing parallel broadcast " + r);
13877            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13878            if (!replaced) {
13879                queue.enqueueParallelBroadcastLocked(r);
13880                queue.scheduleBroadcastsLocked();
13881            }
13882            registeredReceivers = null;
13883            NR = 0;
13884        }
13885
13886        // Merge into one list.
13887        int ir = 0;
13888        if (receivers != null) {
13889            // A special case for PACKAGE_ADDED: do not allow the package
13890            // being added to see this broadcast.  This prevents them from
13891            // using this as a back door to get run as soon as they are
13892            // installed.  Maybe in the future we want to have a special install
13893            // broadcast or such for apps, but we'd like to deliberately make
13894            // this decision.
13895            String skipPackages[] = null;
13896            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13897                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13898                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13899                Uri data = intent.getData();
13900                if (data != null) {
13901                    String pkgName = data.getSchemeSpecificPart();
13902                    if (pkgName != null) {
13903                        skipPackages = new String[] { pkgName };
13904                    }
13905                }
13906            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13907                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13908            }
13909            if (skipPackages != null && (skipPackages.length > 0)) {
13910                for (String skipPackage : skipPackages) {
13911                    if (skipPackage != null) {
13912                        int NT = receivers.size();
13913                        for (int it=0; it<NT; it++) {
13914                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13915                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13916                                receivers.remove(it);
13917                                it--;
13918                                NT--;
13919                            }
13920                        }
13921                    }
13922                }
13923            }
13924
13925            int NT = receivers != null ? receivers.size() : 0;
13926            int it = 0;
13927            ResolveInfo curt = null;
13928            BroadcastFilter curr = null;
13929            while (it < NT && ir < NR) {
13930                if (curt == null) {
13931                    curt = (ResolveInfo)receivers.get(it);
13932                }
13933                if (curr == null) {
13934                    curr = registeredReceivers.get(ir);
13935                }
13936                if (curr.getPriority() >= curt.priority) {
13937                    // Insert this broadcast record into the final list.
13938                    receivers.add(it, curr);
13939                    ir++;
13940                    curr = null;
13941                    it++;
13942                    NT++;
13943                } else {
13944                    // Skip to the next ResolveInfo in the final list.
13945                    it++;
13946                    curt = null;
13947                }
13948            }
13949        }
13950        while (ir < NR) {
13951            if (receivers == null) {
13952                receivers = new ArrayList();
13953            }
13954            receivers.add(registeredReceivers.get(ir));
13955            ir++;
13956        }
13957
13958        if ((receivers != null && receivers.size() > 0)
13959                || resultTo != null) {
13960            BroadcastQueue queue = broadcastQueueForIntent(intent);
13961            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13962                    callerPackage, callingPid, callingUid, resolvedType,
13963                    requiredPermission, appOp, receivers, resultTo, resultCode,
13964                    resultData, map, ordered, sticky, false, userId);
13965            if (DEBUG_BROADCAST) Slog.v(
13966                    TAG, "Enqueueing ordered broadcast " + r
13967                    + ": prev had " + queue.mOrderedBroadcasts.size());
13968            if (DEBUG_BROADCAST) {
13969                int seq = r.intent.getIntExtra("seq", -1);
13970                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13971            }
13972            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13973            if (!replaced) {
13974                queue.enqueueOrderedBroadcastLocked(r);
13975                queue.scheduleBroadcastsLocked();
13976            }
13977        }
13978
13979        return ActivityManager.BROADCAST_SUCCESS;
13980    }
13981
13982    final Intent verifyBroadcastLocked(Intent intent) {
13983        // Refuse possible leaked file descriptors
13984        if (intent != null && intent.hasFileDescriptors() == true) {
13985            throw new IllegalArgumentException("File descriptors passed in Intent");
13986        }
13987
13988        int flags = intent.getFlags();
13989
13990        if (!mProcessesReady) {
13991            // if the caller really truly claims to know what they're doing, go
13992            // ahead and allow the broadcast without launching any receivers
13993            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13994                intent = new Intent(intent);
13995                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13996            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13997                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13998                        + " before boot completion");
13999                throw new IllegalStateException("Cannot broadcast before boot completed");
14000            }
14001        }
14002
14003        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14004            throw new IllegalArgumentException(
14005                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14006        }
14007
14008        return intent;
14009    }
14010
14011    public final int broadcastIntent(IApplicationThread caller,
14012            Intent intent, String resolvedType, IIntentReceiver resultTo,
14013            int resultCode, String resultData, Bundle map,
14014            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14015        enforceNotIsolatedCaller("broadcastIntent");
14016        synchronized(this) {
14017            intent = verifyBroadcastLocked(intent);
14018
14019            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14020            final int callingPid = Binder.getCallingPid();
14021            final int callingUid = Binder.getCallingUid();
14022            final long origId = Binder.clearCallingIdentity();
14023            int res = broadcastIntentLocked(callerApp,
14024                    callerApp != null ? callerApp.info.packageName : null,
14025                    intent, resolvedType, resultTo,
14026                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14027                    callingPid, callingUid, userId);
14028            Binder.restoreCallingIdentity(origId);
14029            return res;
14030        }
14031    }
14032
14033    int broadcastIntentInPackage(String packageName, int uid,
14034            Intent intent, String resolvedType, IIntentReceiver resultTo,
14035            int resultCode, String resultData, Bundle map,
14036            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14037        synchronized(this) {
14038            intent = verifyBroadcastLocked(intent);
14039
14040            final long origId = Binder.clearCallingIdentity();
14041            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14042                    resultTo, resultCode, resultData, map, requiredPermission,
14043                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14044            Binder.restoreCallingIdentity(origId);
14045            return res;
14046        }
14047    }
14048
14049    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14050        // Refuse possible leaked file descriptors
14051        if (intent != null && intent.hasFileDescriptors() == true) {
14052            throw new IllegalArgumentException("File descriptors passed in Intent");
14053        }
14054
14055        userId = handleIncomingUser(Binder.getCallingPid(),
14056                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14057
14058        synchronized(this) {
14059            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14060                    != PackageManager.PERMISSION_GRANTED) {
14061                String msg = "Permission Denial: unbroadcastIntent() from pid="
14062                        + Binder.getCallingPid()
14063                        + ", uid=" + Binder.getCallingUid()
14064                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14065                Slog.w(TAG, msg);
14066                throw new SecurityException(msg);
14067            }
14068            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14069            if (stickies != null) {
14070                ArrayList<Intent> list = stickies.get(intent.getAction());
14071                if (list != null) {
14072                    int N = list.size();
14073                    int i;
14074                    for (i=0; i<N; i++) {
14075                        if (intent.filterEquals(list.get(i))) {
14076                            list.remove(i);
14077                            break;
14078                        }
14079                    }
14080                    if (list.size() <= 0) {
14081                        stickies.remove(intent.getAction());
14082                    }
14083                }
14084                if (stickies.size() <= 0) {
14085                    mStickyBroadcasts.remove(userId);
14086                }
14087            }
14088        }
14089    }
14090
14091    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14092            String resultData, Bundle resultExtras, boolean resultAbort) {
14093        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14094        if (r == null) {
14095            Slog.w(TAG, "finishReceiver called but not found on queue");
14096            return false;
14097        }
14098
14099        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14100    }
14101
14102    void backgroundServicesFinishedLocked(int userId) {
14103        for (BroadcastQueue queue : mBroadcastQueues) {
14104            queue.backgroundServicesFinishedLocked(userId);
14105        }
14106    }
14107
14108    public void finishReceiver(IBinder who, int resultCode, String resultData,
14109            Bundle resultExtras, boolean resultAbort) {
14110        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14111
14112        // Refuse possible leaked file descriptors
14113        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14114            throw new IllegalArgumentException("File descriptors passed in Bundle");
14115        }
14116
14117        final long origId = Binder.clearCallingIdentity();
14118        try {
14119            boolean doNext = false;
14120            BroadcastRecord r;
14121
14122            synchronized(this) {
14123                r = broadcastRecordForReceiverLocked(who);
14124                if (r != null) {
14125                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14126                        resultData, resultExtras, resultAbort, true);
14127                }
14128            }
14129
14130            if (doNext) {
14131                r.queue.processNextBroadcast(false);
14132            }
14133            trimApplications();
14134        } finally {
14135            Binder.restoreCallingIdentity(origId);
14136        }
14137    }
14138
14139    // =========================================================
14140    // INSTRUMENTATION
14141    // =========================================================
14142
14143    public boolean startInstrumentation(ComponentName className,
14144            String profileFile, int flags, Bundle arguments,
14145            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14146            int userId) {
14147        enforceNotIsolatedCaller("startInstrumentation");
14148        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14149                userId, false, true, "startInstrumentation", null);
14150        // Refuse possible leaked file descriptors
14151        if (arguments != null && arguments.hasFileDescriptors()) {
14152            throw new IllegalArgumentException("File descriptors passed in Bundle");
14153        }
14154
14155        synchronized(this) {
14156            InstrumentationInfo ii = null;
14157            ApplicationInfo ai = null;
14158            try {
14159                ii = mContext.getPackageManager().getInstrumentationInfo(
14160                    className, STOCK_PM_FLAGS);
14161                ai = AppGlobals.getPackageManager().getApplicationInfo(
14162                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14163            } catch (PackageManager.NameNotFoundException e) {
14164            } catch (RemoteException e) {
14165            }
14166            if (ii == null) {
14167                reportStartInstrumentationFailure(watcher, className,
14168                        "Unable to find instrumentation info for: " + className);
14169                return false;
14170            }
14171            if (ai == null) {
14172                reportStartInstrumentationFailure(watcher, className,
14173                        "Unable to find instrumentation target package: " + ii.targetPackage);
14174                return false;
14175            }
14176
14177            int match = mContext.getPackageManager().checkSignatures(
14178                    ii.targetPackage, ii.packageName);
14179            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14180                String msg = "Permission Denial: starting instrumentation "
14181                        + className + " from pid="
14182                        + Binder.getCallingPid()
14183                        + ", uid=" + Binder.getCallingPid()
14184                        + " not allowed because package " + ii.packageName
14185                        + " does not have a signature matching the target "
14186                        + ii.targetPackage;
14187                reportStartInstrumentationFailure(watcher, className, msg);
14188                throw new SecurityException(msg);
14189            }
14190
14191            final long origId = Binder.clearCallingIdentity();
14192            // Instrumentation can kill and relaunch even persistent processes
14193            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14194                    "start instr");
14195            ProcessRecord app = addAppLocked(ai, false);
14196            app.instrumentationClass = className;
14197            app.instrumentationInfo = ai;
14198            app.instrumentationProfileFile = profileFile;
14199            app.instrumentationArguments = arguments;
14200            app.instrumentationWatcher = watcher;
14201            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14202            app.instrumentationResultClass = className;
14203            Binder.restoreCallingIdentity(origId);
14204        }
14205
14206        return true;
14207    }
14208
14209    /**
14210     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14211     * error to the logs, but if somebody is watching, send the report there too.  This enables
14212     * the "am" command to report errors with more information.
14213     *
14214     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14215     * @param cn The component name of the instrumentation.
14216     * @param report The error report.
14217     */
14218    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14219            ComponentName cn, String report) {
14220        Slog.w(TAG, report);
14221        try {
14222            if (watcher != null) {
14223                Bundle results = new Bundle();
14224                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14225                results.putString("Error", report);
14226                watcher.instrumentationStatus(cn, -1, results);
14227            }
14228        } catch (RemoteException e) {
14229            Slog.w(TAG, e);
14230        }
14231    }
14232
14233    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14234        if (app.instrumentationWatcher != null) {
14235            try {
14236                // NOTE:  IInstrumentationWatcher *must* be oneway here
14237                app.instrumentationWatcher.instrumentationFinished(
14238                    app.instrumentationClass,
14239                    resultCode,
14240                    results);
14241            } catch (RemoteException e) {
14242            }
14243        }
14244        if (app.instrumentationUiAutomationConnection != null) {
14245            try {
14246                app.instrumentationUiAutomationConnection.shutdown();
14247            } catch (RemoteException re) {
14248                /* ignore */
14249            }
14250            // Only a UiAutomation can set this flag and now that
14251            // it is finished we make sure it is reset to its default.
14252            mUserIsMonkey = false;
14253        }
14254        app.instrumentationWatcher = null;
14255        app.instrumentationUiAutomationConnection = null;
14256        app.instrumentationClass = null;
14257        app.instrumentationInfo = null;
14258        app.instrumentationProfileFile = null;
14259        app.instrumentationArguments = null;
14260
14261        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14262                "finished inst");
14263    }
14264
14265    public void finishInstrumentation(IApplicationThread target,
14266            int resultCode, Bundle results) {
14267        int userId = UserHandle.getCallingUserId();
14268        // Refuse possible leaked file descriptors
14269        if (results != null && results.hasFileDescriptors()) {
14270            throw new IllegalArgumentException("File descriptors passed in Intent");
14271        }
14272
14273        synchronized(this) {
14274            ProcessRecord app = getRecordForAppLocked(target);
14275            if (app == null) {
14276                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14277                return;
14278            }
14279            final long origId = Binder.clearCallingIdentity();
14280            finishInstrumentationLocked(app, resultCode, results);
14281            Binder.restoreCallingIdentity(origId);
14282        }
14283    }
14284
14285    // =========================================================
14286    // CONFIGURATION
14287    // =========================================================
14288
14289    public ConfigurationInfo getDeviceConfigurationInfo() {
14290        ConfigurationInfo config = new ConfigurationInfo();
14291        synchronized (this) {
14292            config.reqTouchScreen = mConfiguration.touchscreen;
14293            config.reqKeyboardType = mConfiguration.keyboard;
14294            config.reqNavigation = mConfiguration.navigation;
14295            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14296                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14297                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14298            }
14299            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14300                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14301                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14302            }
14303            config.reqGlEsVersion = GL_ES_VERSION;
14304        }
14305        return config;
14306    }
14307
14308    ActivityStack getFocusedStack() {
14309        return mStackSupervisor.getFocusedStack();
14310    }
14311
14312    public Configuration getConfiguration() {
14313        Configuration ci;
14314        synchronized(this) {
14315            ci = new Configuration(mConfiguration);
14316        }
14317        return ci;
14318    }
14319
14320    public void updatePersistentConfiguration(Configuration values) {
14321        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14322                "updateConfiguration()");
14323        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14324                "updateConfiguration()");
14325        if (values == null) {
14326            throw new NullPointerException("Configuration must not be null");
14327        }
14328
14329        synchronized(this) {
14330            final long origId = Binder.clearCallingIdentity();
14331            updateConfigurationLocked(values, null, true, false);
14332            Binder.restoreCallingIdentity(origId);
14333        }
14334    }
14335
14336    public void updateConfiguration(Configuration values) {
14337        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14338                "updateConfiguration()");
14339
14340        synchronized(this) {
14341            if (values == null && mWindowManager != null) {
14342                // sentinel: fetch the current configuration from the window manager
14343                values = mWindowManager.computeNewConfiguration();
14344            }
14345
14346            if (mWindowManager != null) {
14347                mProcessList.applyDisplaySize(mWindowManager);
14348            }
14349
14350            final long origId = Binder.clearCallingIdentity();
14351            if (values != null) {
14352                Settings.System.clearConfiguration(values);
14353            }
14354            updateConfigurationLocked(values, null, false, false);
14355            Binder.restoreCallingIdentity(origId);
14356        }
14357    }
14358
14359    /**
14360     * Do either or both things: (1) change the current configuration, and (2)
14361     * make sure the given activity is running with the (now) current
14362     * configuration.  Returns true if the activity has been left running, or
14363     * false if <var>starting</var> is being destroyed to match the new
14364     * configuration.
14365     * @param persistent TODO
14366     */
14367    boolean updateConfigurationLocked(Configuration values,
14368            ActivityRecord starting, boolean persistent, boolean initLocale) {
14369        int changes = 0;
14370
14371        if (values != null) {
14372            Configuration newConfig = new Configuration(mConfiguration);
14373            changes = newConfig.updateFrom(values);
14374            if (changes != 0) {
14375                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14376                    Slog.i(TAG, "Updating configuration to: " + values);
14377                }
14378
14379                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14380
14381                if (values.locale != null && !initLocale) {
14382                    saveLocaleLocked(values.locale,
14383                                     !values.locale.equals(mConfiguration.locale),
14384                                     values.userSetLocale);
14385                }
14386
14387                mConfigurationSeq++;
14388                if (mConfigurationSeq <= 0) {
14389                    mConfigurationSeq = 1;
14390                }
14391                newConfig.seq = mConfigurationSeq;
14392                mConfiguration = newConfig;
14393                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14394
14395                final Configuration configCopy = new Configuration(mConfiguration);
14396
14397                // TODO: If our config changes, should we auto dismiss any currently
14398                // showing dialogs?
14399                mShowDialogs = shouldShowDialogs(newConfig);
14400
14401                AttributeCache ac = AttributeCache.instance();
14402                if (ac != null) {
14403                    ac.updateConfiguration(configCopy);
14404                }
14405
14406                // Make sure all resources in our process are updated
14407                // right now, so that anyone who is going to retrieve
14408                // resource values after we return will be sure to get
14409                // the new ones.  This is especially important during
14410                // boot, where the first config change needs to guarantee
14411                // all resources have that config before following boot
14412                // code is executed.
14413                mSystemThread.applyConfigurationToResources(configCopy);
14414
14415                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14416                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14417                    msg.obj = new Configuration(configCopy);
14418                    mHandler.sendMessage(msg);
14419                }
14420
14421                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14422                    ProcessRecord app = mLruProcesses.get(i);
14423                    try {
14424                        if (app.thread != null) {
14425                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14426                                    + app.processName + " new config " + mConfiguration);
14427                            app.thread.scheduleConfigurationChanged(configCopy);
14428                        }
14429                    } catch (Exception e) {
14430                    }
14431                }
14432                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14433                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14434                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14435                        | Intent.FLAG_RECEIVER_FOREGROUND);
14436                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14437                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14438                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14439                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14440                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14441                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14442                    broadcastIntentLocked(null, null, intent,
14443                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14444                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14445                }
14446            }
14447        }
14448
14449        boolean kept = true;
14450        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14451        // mainStack is null during startup.
14452        if (mainStack != null) {
14453            if (changes != 0 && starting == null) {
14454                // If the configuration changed, and the caller is not already
14455                // in the process of starting an activity, then find the top
14456                // activity to check if its configuration needs to change.
14457                starting = mainStack.topRunningActivityLocked(null);
14458            }
14459
14460            if (starting != null) {
14461                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14462                // And we need to make sure at this point that all other activities
14463                // are made visible with the correct configuration.
14464                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14465            }
14466        }
14467
14468        if (values != null && mWindowManager != null) {
14469            mWindowManager.setNewConfiguration(mConfiguration);
14470        }
14471
14472        return kept;
14473    }
14474
14475    /**
14476     * Decide based on the configuration whether we should shouw the ANR,
14477     * crash, etc dialogs.  The idea is that if there is no affordnace to
14478     * press the on-screen buttons, we shouldn't show the dialog.
14479     *
14480     * A thought: SystemUI might also want to get told about this, the Power
14481     * dialog / global actions also might want different behaviors.
14482     */
14483    private static final boolean shouldShowDialogs(Configuration config) {
14484        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14485                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14486    }
14487
14488    /**
14489     * Save the locale.  You must be inside a synchronized (this) block.
14490     */
14491    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14492        if(isDiff) {
14493            SystemProperties.set("user.language", l.getLanguage());
14494            SystemProperties.set("user.region", l.getCountry());
14495        }
14496
14497        if(isPersist) {
14498            SystemProperties.set("persist.sys.language", l.getLanguage());
14499            SystemProperties.set("persist.sys.country", l.getCountry());
14500            SystemProperties.set("persist.sys.localevar", l.getVariant());
14501        }
14502    }
14503
14504    @Override
14505    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14506        ActivityRecord srec = ActivityRecord.forToken(token);
14507        return srec != null && srec.task.affinity != null &&
14508                srec.task.affinity.equals(destAffinity);
14509    }
14510
14511    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14512            Intent resultData) {
14513
14514        synchronized (this) {
14515            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14516            if (stack != null) {
14517                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14518            }
14519            return false;
14520        }
14521    }
14522
14523    public int getLaunchedFromUid(IBinder activityToken) {
14524        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14525        if (srec == null) {
14526            return -1;
14527        }
14528        return srec.launchedFromUid;
14529    }
14530
14531    public String getLaunchedFromPackage(IBinder activityToken) {
14532        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14533        if (srec == null) {
14534            return null;
14535        }
14536        return srec.launchedFromPackage;
14537    }
14538
14539    // =========================================================
14540    // LIFETIME MANAGEMENT
14541    // =========================================================
14542
14543    // Returns which broadcast queue the app is the current [or imminent] receiver
14544    // on, or 'null' if the app is not an active broadcast recipient.
14545    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14546        BroadcastRecord r = app.curReceiver;
14547        if (r != null) {
14548            return r.queue;
14549        }
14550
14551        // It's not the current receiver, but it might be starting up to become one
14552        synchronized (this) {
14553            for (BroadcastQueue queue : mBroadcastQueues) {
14554                r = queue.mPendingBroadcast;
14555                if (r != null && r.curApp == app) {
14556                    // found it; report which queue it's in
14557                    return queue;
14558                }
14559            }
14560        }
14561
14562        return null;
14563    }
14564
14565    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14566            boolean doingAll, long now) {
14567        if (mAdjSeq == app.adjSeq) {
14568            // This adjustment has already been computed.
14569            return app.curRawAdj;
14570        }
14571
14572        if (app.thread == null) {
14573            app.adjSeq = mAdjSeq;
14574            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14575            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14576            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14577        }
14578
14579        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14580        app.adjSource = null;
14581        app.adjTarget = null;
14582        app.empty = false;
14583        app.cached = false;
14584
14585        final int activitiesSize = app.activities.size();
14586
14587        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14588            // The max adjustment doesn't allow this app to be anything
14589            // below foreground, so it is not worth doing work for it.
14590            app.adjType = "fixed";
14591            app.adjSeq = mAdjSeq;
14592            app.curRawAdj = app.maxAdj;
14593            app.foregroundActivities = false;
14594            app.keeping = true;
14595            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14596            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14597            // System processes can do UI, and when they do we want to have
14598            // them trim their memory after the user leaves the UI.  To
14599            // facilitate this, here we need to determine whether or not it
14600            // is currently showing UI.
14601            app.systemNoUi = true;
14602            if (app == TOP_APP) {
14603                app.systemNoUi = false;
14604            } else if (activitiesSize > 0) {
14605                for (int j = 0; j < activitiesSize; j++) {
14606                    final ActivityRecord r = app.activities.get(j);
14607                    if (r.visible) {
14608                        app.systemNoUi = false;
14609                    }
14610                }
14611            }
14612            if (!app.systemNoUi) {
14613                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14614            }
14615            return (app.curAdj=app.maxAdj);
14616        }
14617
14618        app.keeping = false;
14619        app.systemNoUi = false;
14620
14621        // Determine the importance of the process, starting with most
14622        // important to least, and assign an appropriate OOM adjustment.
14623        int adj;
14624        int schedGroup;
14625        int procState;
14626        boolean foregroundActivities = false;
14627        boolean interesting = false;
14628        BroadcastQueue queue;
14629        if (app == TOP_APP) {
14630            // The last app on the list is the foreground app.
14631            adj = ProcessList.FOREGROUND_APP_ADJ;
14632            schedGroup = Process.THREAD_GROUP_DEFAULT;
14633            app.adjType = "top-activity";
14634            foregroundActivities = true;
14635            interesting = true;
14636            procState = ActivityManager.PROCESS_STATE_TOP;
14637        } else if (app.instrumentationClass != null) {
14638            // Don't want to kill running instrumentation.
14639            adj = ProcessList.FOREGROUND_APP_ADJ;
14640            schedGroup = Process.THREAD_GROUP_DEFAULT;
14641            app.adjType = "instrumentation";
14642            interesting = true;
14643            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14644        } else if ((queue = isReceivingBroadcast(app)) != null) {
14645            // An app that is currently receiving a broadcast also
14646            // counts as being in the foreground for OOM killer purposes.
14647            // It's placed in a sched group based on the nature of the
14648            // broadcast as reflected by which queue it's active in.
14649            adj = ProcessList.FOREGROUND_APP_ADJ;
14650            schedGroup = (queue == mFgBroadcastQueue)
14651                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14652            app.adjType = "broadcast";
14653            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14654        } else if (app.executingServices.size() > 0) {
14655            // An app that is currently executing a service callback also
14656            // counts as being in the foreground.
14657            adj = ProcessList.FOREGROUND_APP_ADJ;
14658            schedGroup = app.execServicesFg ?
14659                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14660            app.adjType = "exec-service";
14661            procState = ActivityManager.PROCESS_STATE_SERVICE;
14662            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14663        } else {
14664            // As far as we know the process is empty.  We may change our mind later.
14665            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14666            // At this point we don't actually know the adjustment.  Use the cached adj
14667            // value that the caller wants us to.
14668            adj = cachedAdj;
14669            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14670            app.cached = true;
14671            app.empty = true;
14672            app.adjType = "cch-empty";
14673        }
14674
14675        // Examine all activities if not already foreground.
14676        if (!foregroundActivities && activitiesSize > 0) {
14677            for (int j = 0; j < activitiesSize; j++) {
14678                final ActivityRecord r = app.activities.get(j);
14679                if (r.app != app) {
14680                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14681                            + app + "?!?");
14682                    continue;
14683                }
14684                if (r.visible) {
14685                    // App has a visible activity; only upgrade adjustment.
14686                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14687                        adj = ProcessList.VISIBLE_APP_ADJ;
14688                        app.adjType = "visible";
14689                    }
14690                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14691                        procState = ActivityManager.PROCESS_STATE_TOP;
14692                    }
14693                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14694                    app.cached = false;
14695                    app.empty = false;
14696                    foregroundActivities = true;
14697                    break;
14698                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14699                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14700                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14701                        app.adjType = "pausing";
14702                    }
14703                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14704                        procState = ActivityManager.PROCESS_STATE_TOP;
14705                    }
14706                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14707                    app.cached = false;
14708                    app.empty = false;
14709                    foregroundActivities = true;
14710                } else if (r.state == ActivityState.STOPPING) {
14711                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14712                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14713                        app.adjType = "stopping";
14714                    }
14715                    // For the process state, we will at this point consider the
14716                    // process to be cached.  It will be cached either as an activity
14717                    // or empty depending on whether the activity is finishing.  We do
14718                    // this so that we can treat the process as cached for purposes of
14719                    // memory trimming (determing current memory level, trim command to
14720                    // send to process) since there can be an arbitrary number of stopping
14721                    // processes and they should soon all go into the cached state.
14722                    if (!r.finishing) {
14723                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14724                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14725                        }
14726                    }
14727                    app.cached = false;
14728                    app.empty = false;
14729                    foregroundActivities = true;
14730                } else {
14731                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14732                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14733                        app.adjType = "cch-act";
14734                    }
14735                }
14736            }
14737        }
14738
14739        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14740            if (app.foregroundServices) {
14741                // The user is aware of this app, so make it visible.
14742                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14743                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14744                app.cached = false;
14745                app.adjType = "fg-service";
14746                schedGroup = Process.THREAD_GROUP_DEFAULT;
14747            } else if (app.forcingToForeground != null) {
14748                // The user is aware of this app, so make it visible.
14749                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14750                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14751                app.cached = false;
14752                app.adjType = "force-fg";
14753                app.adjSource = app.forcingToForeground;
14754                schedGroup = Process.THREAD_GROUP_DEFAULT;
14755            }
14756        }
14757
14758        if (app.foregroundServices) {
14759            interesting = true;
14760        }
14761
14762        if (app == mHeavyWeightProcess) {
14763            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14764                // We don't want to kill the current heavy-weight process.
14765                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14766                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14767                app.cached = false;
14768                app.adjType = "heavy";
14769            }
14770            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14771                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14772            }
14773        }
14774
14775        if (app == mHomeProcess) {
14776            if (adj > ProcessList.HOME_APP_ADJ) {
14777                // This process is hosting what we currently consider to be the
14778                // home app, so we don't want to let it go into the background.
14779                adj = ProcessList.HOME_APP_ADJ;
14780                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14781                app.cached = false;
14782                app.adjType = "home";
14783            }
14784            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14785                procState = ActivityManager.PROCESS_STATE_HOME;
14786            }
14787        }
14788
14789        if (app == mPreviousProcess && app.activities.size() > 0) {
14790            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14791                // This was the previous process that showed UI to the user.
14792                // We want to try to keep it around more aggressively, to give
14793                // a good experience around switching between two apps.
14794                adj = ProcessList.PREVIOUS_APP_ADJ;
14795                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14796                app.cached = false;
14797                app.adjType = "previous";
14798            }
14799            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14800                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14801            }
14802        }
14803
14804        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14805                + " reason=" + app.adjType);
14806
14807        // By default, we use the computed adjustment.  It may be changed if
14808        // there are applications dependent on our services or providers, but
14809        // this gives us a baseline and makes sure we don't get into an
14810        // infinite recursion.
14811        app.adjSeq = mAdjSeq;
14812        app.curRawAdj = adj;
14813        app.hasStartedServices = false;
14814
14815        if (mBackupTarget != null && app == mBackupTarget.app) {
14816            // If possible we want to avoid killing apps while they're being backed up
14817            if (adj > ProcessList.BACKUP_APP_ADJ) {
14818                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14819                adj = ProcessList.BACKUP_APP_ADJ;
14820                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14821                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14822                }
14823                app.adjType = "backup";
14824                app.cached = false;
14825            }
14826            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14827                procState = ActivityManager.PROCESS_STATE_BACKUP;
14828            }
14829        }
14830
14831        boolean mayBeTop = false;
14832
14833        for (int is = app.services.size()-1;
14834                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14835                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14836                        || procState > ActivityManager.PROCESS_STATE_TOP);
14837                is--) {
14838            ServiceRecord s = app.services.valueAt(is);
14839            if (s.startRequested) {
14840                app.hasStartedServices = true;
14841                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14842                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14843                }
14844                if (app.hasShownUi && app != mHomeProcess) {
14845                    // If this process has shown some UI, let it immediately
14846                    // go to the LRU list because it may be pretty heavy with
14847                    // UI stuff.  We'll tag it with a label just to help
14848                    // debug and understand what is going on.
14849                    if (adj > ProcessList.SERVICE_ADJ) {
14850                        app.adjType = "cch-started-ui-services";
14851                    }
14852                } else {
14853                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14854                        // This service has seen some activity within
14855                        // recent memory, so we will keep its process ahead
14856                        // of the background processes.
14857                        if (adj > ProcessList.SERVICE_ADJ) {
14858                            adj = ProcessList.SERVICE_ADJ;
14859                            app.adjType = "started-services";
14860                            app.cached = false;
14861                        }
14862                    }
14863                    // If we have let the service slide into the background
14864                    // state, still have some text describing what it is doing
14865                    // even though the service no longer has an impact.
14866                    if (adj > ProcessList.SERVICE_ADJ) {
14867                        app.adjType = "cch-started-services";
14868                    }
14869                }
14870                // Don't kill this process because it is doing work; it
14871                // has said it is doing work.
14872                app.keeping = true;
14873            }
14874            for (int conni = s.connections.size()-1;
14875                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14876                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14877                            || procState > ActivityManager.PROCESS_STATE_TOP);
14878                    conni--) {
14879                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14880                for (int i = 0;
14881                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14882                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14883                                || procState > ActivityManager.PROCESS_STATE_TOP);
14884                        i++) {
14885                    // XXX should compute this based on the max of
14886                    // all connected clients.
14887                    ConnectionRecord cr = clist.get(i);
14888                    if (cr.binding.client == app) {
14889                        // Binding to ourself is not interesting.
14890                        continue;
14891                    }
14892                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14893                        ProcessRecord client = cr.binding.client;
14894                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14895                                TOP_APP, doingAll, now);
14896                        int clientProcState = client.curProcState;
14897                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14898                            // If the other app is cached for any reason, for purposes here
14899                            // we are going to consider it empty.  The specific cached state
14900                            // doesn't propagate except under certain conditions.
14901                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14902                        }
14903                        String adjType = null;
14904                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14905                            // Not doing bind OOM management, so treat
14906                            // this guy more like a started service.
14907                            if (app.hasShownUi && app != mHomeProcess) {
14908                                // If this process has shown some UI, let it immediately
14909                                // go to the LRU list because it may be pretty heavy with
14910                                // UI stuff.  We'll tag it with a label just to help
14911                                // debug and understand what is going on.
14912                                if (adj > clientAdj) {
14913                                    adjType = "cch-bound-ui-services";
14914                                }
14915                                app.cached = false;
14916                                clientAdj = adj;
14917                                clientProcState = procState;
14918                            } else {
14919                                if (now >= (s.lastActivity
14920                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14921                                    // This service has not seen activity within
14922                                    // recent memory, so allow it to drop to the
14923                                    // LRU list if there is no other reason to keep
14924                                    // it around.  We'll also tag it with a label just
14925                                    // to help debug and undertand what is going on.
14926                                    if (adj > clientAdj) {
14927                                        adjType = "cch-bound-services";
14928                                    }
14929                                    clientAdj = adj;
14930                                }
14931                            }
14932                        }
14933                        if (adj > clientAdj) {
14934                            // If this process has recently shown UI, and
14935                            // the process that is binding to it is less
14936                            // important than being visible, then we don't
14937                            // care about the binding as much as we care
14938                            // about letting this process get into the LRU
14939                            // list to be killed and restarted if needed for
14940                            // memory.
14941                            if (app.hasShownUi && app != mHomeProcess
14942                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14943                                adjType = "cch-bound-ui-services";
14944                            } else {
14945                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14946                                        |Context.BIND_IMPORTANT)) != 0) {
14947                                    adj = clientAdj;
14948                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14949                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14950                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14951                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14952                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14953                                    adj = clientAdj;
14954                                } else {
14955                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14956                                        adj = ProcessList.VISIBLE_APP_ADJ;
14957                                    }
14958                                }
14959                                if (!client.cached) {
14960                                    app.cached = false;
14961                                }
14962                                if (client.keeping) {
14963                                    app.keeping = true;
14964                                }
14965                                adjType = "service";
14966                            }
14967                        }
14968                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14969                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14970                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14971                            }
14972                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14973                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14974                                    // Special handling of clients who are in the top state.
14975                                    // We *may* want to consider this process to be in the
14976                                    // top state as well, but only if there is not another
14977                                    // reason for it to be running.  Being on the top is a
14978                                    // special state, meaning you are specifically running
14979                                    // for the current top app.  If the process is already
14980                                    // running in the background for some other reason, it
14981                                    // is more important to continue considering it to be
14982                                    // in the background state.
14983                                    mayBeTop = true;
14984                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14985                                } else {
14986                                    // Special handling for above-top states (persistent
14987                                    // processes).  These should not bring the current process
14988                                    // into the top state, since they are not on top.  Instead
14989                                    // give them the best state after that.
14990                                    clientProcState =
14991                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14992                                }
14993                            }
14994                        } else {
14995                            if (clientProcState <
14996                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14997                                clientProcState =
14998                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14999                            }
15000                        }
15001                        if (procState > clientProcState) {
15002                            procState = clientProcState;
15003                        }
15004                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15005                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15006                            app.pendingUiClean = true;
15007                        }
15008                        if (adjType != null) {
15009                            app.adjType = adjType;
15010                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15011                                    .REASON_SERVICE_IN_USE;
15012                            app.adjSource = cr.binding.client;
15013                            app.adjSourceOom = clientAdj;
15014                            app.adjTarget = s.name;
15015                        }
15016                    }
15017                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15018                        app.treatLikeActivity = true;
15019                    }
15020                    final ActivityRecord a = cr.activity;
15021                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15022                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15023                                (a.visible || a.state == ActivityState.RESUMED
15024                                 || a.state == ActivityState.PAUSING)) {
15025                            adj = ProcessList.FOREGROUND_APP_ADJ;
15026                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15027                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15028                            }
15029                            app.cached = false;
15030                            app.adjType = "service";
15031                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15032                                    .REASON_SERVICE_IN_USE;
15033                            app.adjSource = a;
15034                            app.adjSourceOom = adj;
15035                            app.adjTarget = s.name;
15036                        }
15037                    }
15038                }
15039            }
15040        }
15041
15042        for (int provi = app.pubProviders.size()-1;
15043                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15044                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15045                        || procState > ActivityManager.PROCESS_STATE_TOP);
15046                provi--) {
15047            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15048            for (int i = cpr.connections.size()-1;
15049                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15050                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15051                            || procState > ActivityManager.PROCESS_STATE_TOP);
15052                    i--) {
15053                ContentProviderConnection conn = cpr.connections.get(i);
15054                ProcessRecord client = conn.client;
15055                if (client == app) {
15056                    // Being our own client is not interesting.
15057                    continue;
15058                }
15059                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15060                int clientProcState = client.curProcState;
15061                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15062                    // If the other app is cached for any reason, for purposes here
15063                    // we are going to consider it empty.
15064                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15065                }
15066                if (adj > clientAdj) {
15067                    if (app.hasShownUi && app != mHomeProcess
15068                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15069                        app.adjType = "cch-ui-provider";
15070                    } else {
15071                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15072                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15073                        app.adjType = "provider";
15074                    }
15075                    app.cached &= client.cached;
15076                    app.keeping |= client.keeping;
15077                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15078                            .REASON_PROVIDER_IN_USE;
15079                    app.adjSource = client;
15080                    app.adjSourceOom = clientAdj;
15081                    app.adjTarget = cpr.name;
15082                }
15083                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15084                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15085                        // Special handling of clients who are in the top state.
15086                        // We *may* want to consider this process to be in the
15087                        // top state as well, but only if there is not another
15088                        // reason for it to be running.  Being on the top is a
15089                        // special state, meaning you are specifically running
15090                        // for the current top app.  If the process is already
15091                        // running in the background for some other reason, it
15092                        // is more important to continue considering it to be
15093                        // in the background state.
15094                        mayBeTop = true;
15095                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15096                    } else {
15097                        // Special handling for above-top states (persistent
15098                        // processes).  These should not bring the current process
15099                        // into the top state, since they are not on top.  Instead
15100                        // give them the best state after that.
15101                        clientProcState =
15102                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15103                    }
15104                }
15105                if (procState > clientProcState) {
15106                    procState = clientProcState;
15107                }
15108                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15109                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15110                }
15111            }
15112            // If the provider has external (non-framework) process
15113            // dependencies, ensure that its adjustment is at least
15114            // FOREGROUND_APP_ADJ.
15115            if (cpr.hasExternalProcessHandles()) {
15116                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15117                    adj = ProcessList.FOREGROUND_APP_ADJ;
15118                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15119                    app.cached = false;
15120                    app.keeping = true;
15121                    app.adjType = "provider";
15122                    app.adjTarget = cpr.name;
15123                }
15124                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15125                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15126                }
15127            }
15128        }
15129
15130        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15131            // A client of one of our services or providers is in the top state.  We
15132            // *may* want to be in the top state, but not if we are already running in
15133            // the background for some other reason.  For the decision here, we are going
15134            // to pick out a few specific states that we want to remain in when a client
15135            // is top (states that tend to be longer-term) and otherwise allow it to go
15136            // to the top state.
15137            switch (procState) {
15138                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15139                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15140                case ActivityManager.PROCESS_STATE_SERVICE:
15141                    // These all are longer-term states, so pull them up to the top
15142                    // of the background states, but not all the way to the top state.
15143                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15144                    break;
15145                default:
15146                    // Otherwise, top is a better choice, so take it.
15147                    procState = ActivityManager.PROCESS_STATE_TOP;
15148                    break;
15149            }
15150        }
15151
15152        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15153            if (app.hasClientActivities) {
15154                // This is a cached process, but with client activities.  Mark it so.
15155                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15156                app.adjType = "cch-client-act";
15157            } else if (app.treatLikeActivity) {
15158                // This is a cached process, but somebody wants us to treat it like it has
15159                // an activity, okay!
15160                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15161                app.adjType = "cch-as-act";
15162            }
15163        }
15164
15165        if (adj == ProcessList.SERVICE_ADJ) {
15166            if (doingAll) {
15167                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15168                mNewNumServiceProcs++;
15169                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15170                if (!app.serviceb) {
15171                    // This service isn't far enough down on the LRU list to
15172                    // normally be a B service, but if we are low on RAM and it
15173                    // is large we want to force it down since we would prefer to
15174                    // keep launcher over it.
15175                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15176                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15177                        app.serviceHighRam = true;
15178                        app.serviceb = true;
15179                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15180                    } else {
15181                        mNewNumAServiceProcs++;
15182                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15183                    }
15184                } else {
15185                    app.serviceHighRam = false;
15186                }
15187            }
15188            if (app.serviceb) {
15189                adj = ProcessList.SERVICE_B_ADJ;
15190            }
15191        }
15192
15193        app.curRawAdj = adj;
15194
15195        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15196        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15197        if (adj > app.maxAdj) {
15198            adj = app.maxAdj;
15199            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15200                schedGroup = Process.THREAD_GROUP_DEFAULT;
15201            }
15202        }
15203        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15204            app.keeping = true;
15205        }
15206
15207        // Do final modification to adj.  Everything we do between here and applying
15208        // the final setAdj must be done in this function, because we will also use
15209        // it when computing the final cached adj later.  Note that we don't need to
15210        // worry about this for max adj above, since max adj will always be used to
15211        // keep it out of the cached vaues.
15212        app.curAdj = app.modifyRawOomAdj(adj);
15213        app.curSchedGroup = schedGroup;
15214        app.curProcState = procState;
15215        app.foregroundActivities = foregroundActivities;
15216
15217        return app.curRawAdj;
15218    }
15219
15220    /**
15221     * Schedule PSS collection of a process.
15222     */
15223    void requestPssLocked(ProcessRecord proc, int procState) {
15224        if (mPendingPssProcesses.contains(proc)) {
15225            return;
15226        }
15227        if (mPendingPssProcesses.size() == 0) {
15228            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15229        }
15230        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15231        proc.pssProcState = procState;
15232        mPendingPssProcesses.add(proc);
15233    }
15234
15235    /**
15236     * Schedule PSS collection of all processes.
15237     */
15238    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15239        if (!always) {
15240            if (now < (mLastFullPssTime +
15241                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15242                return;
15243            }
15244        }
15245        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15246        mLastFullPssTime = now;
15247        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15248        mPendingPssProcesses.clear();
15249        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15250            ProcessRecord app = mLruProcesses.get(i);
15251            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15252                app.pssProcState = app.setProcState;
15253                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15254                        isSleeping(), now);
15255                mPendingPssProcesses.add(app);
15256            }
15257        }
15258        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15259    }
15260
15261    /**
15262     * Ask a given process to GC right now.
15263     */
15264    final void performAppGcLocked(ProcessRecord app) {
15265        try {
15266            app.lastRequestedGc = SystemClock.uptimeMillis();
15267            if (app.thread != null) {
15268                if (app.reportLowMemory) {
15269                    app.reportLowMemory = false;
15270                    app.thread.scheduleLowMemory();
15271                } else {
15272                    app.thread.processInBackground();
15273                }
15274            }
15275        } catch (Exception e) {
15276            // whatever.
15277        }
15278    }
15279
15280    /**
15281     * Returns true if things are idle enough to perform GCs.
15282     */
15283    private final boolean canGcNowLocked() {
15284        boolean processingBroadcasts = false;
15285        for (BroadcastQueue q : mBroadcastQueues) {
15286            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15287                processingBroadcasts = true;
15288            }
15289        }
15290        return !processingBroadcasts
15291                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15292    }
15293
15294    /**
15295     * Perform GCs on all processes that are waiting for it, but only
15296     * if things are idle.
15297     */
15298    final void performAppGcsLocked() {
15299        final int N = mProcessesToGc.size();
15300        if (N <= 0) {
15301            return;
15302        }
15303        if (canGcNowLocked()) {
15304            while (mProcessesToGc.size() > 0) {
15305                ProcessRecord proc = mProcessesToGc.remove(0);
15306                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15307                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15308                            <= SystemClock.uptimeMillis()) {
15309                        // To avoid spamming the system, we will GC processes one
15310                        // at a time, waiting a few seconds between each.
15311                        performAppGcLocked(proc);
15312                        scheduleAppGcsLocked();
15313                        return;
15314                    } else {
15315                        // It hasn't been long enough since we last GCed this
15316                        // process...  put it in the list to wait for its time.
15317                        addProcessToGcListLocked(proc);
15318                        break;
15319                    }
15320                }
15321            }
15322
15323            scheduleAppGcsLocked();
15324        }
15325    }
15326
15327    /**
15328     * If all looks good, perform GCs on all processes waiting for them.
15329     */
15330    final void performAppGcsIfAppropriateLocked() {
15331        if (canGcNowLocked()) {
15332            performAppGcsLocked();
15333            return;
15334        }
15335        // Still not idle, wait some more.
15336        scheduleAppGcsLocked();
15337    }
15338
15339    /**
15340     * Schedule the execution of all pending app GCs.
15341     */
15342    final void scheduleAppGcsLocked() {
15343        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15344
15345        if (mProcessesToGc.size() > 0) {
15346            // Schedule a GC for the time to the next process.
15347            ProcessRecord proc = mProcessesToGc.get(0);
15348            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15349
15350            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15351            long now = SystemClock.uptimeMillis();
15352            if (when < (now+GC_TIMEOUT)) {
15353                when = now + GC_TIMEOUT;
15354            }
15355            mHandler.sendMessageAtTime(msg, when);
15356        }
15357    }
15358
15359    /**
15360     * Add a process to the array of processes waiting to be GCed.  Keeps the
15361     * list in sorted order by the last GC time.  The process can't already be
15362     * on the list.
15363     */
15364    final void addProcessToGcListLocked(ProcessRecord proc) {
15365        boolean added = false;
15366        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15367            if (mProcessesToGc.get(i).lastRequestedGc <
15368                    proc.lastRequestedGc) {
15369                added = true;
15370                mProcessesToGc.add(i+1, proc);
15371                break;
15372            }
15373        }
15374        if (!added) {
15375            mProcessesToGc.add(0, proc);
15376        }
15377    }
15378
15379    /**
15380     * Set up to ask a process to GC itself.  This will either do it
15381     * immediately, or put it on the list of processes to gc the next
15382     * time things are idle.
15383     */
15384    final void scheduleAppGcLocked(ProcessRecord app) {
15385        long now = SystemClock.uptimeMillis();
15386        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15387            return;
15388        }
15389        if (!mProcessesToGc.contains(app)) {
15390            addProcessToGcListLocked(app);
15391            scheduleAppGcsLocked();
15392        }
15393    }
15394
15395    final void checkExcessivePowerUsageLocked(boolean doKills) {
15396        updateCpuStatsNow();
15397
15398        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15399        boolean doWakeKills = doKills;
15400        boolean doCpuKills = doKills;
15401        if (mLastPowerCheckRealtime == 0) {
15402            doWakeKills = false;
15403        }
15404        if (mLastPowerCheckUptime == 0) {
15405            doCpuKills = false;
15406        }
15407        if (stats.isScreenOn()) {
15408            doWakeKills = false;
15409        }
15410        final long curRealtime = SystemClock.elapsedRealtime();
15411        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15412        final long curUptime = SystemClock.uptimeMillis();
15413        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15414        mLastPowerCheckRealtime = curRealtime;
15415        mLastPowerCheckUptime = curUptime;
15416        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15417            doWakeKills = false;
15418        }
15419        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15420            doCpuKills = false;
15421        }
15422        int i = mLruProcesses.size();
15423        while (i > 0) {
15424            i--;
15425            ProcessRecord app = mLruProcesses.get(i);
15426            if (!app.keeping) {
15427                long wtime;
15428                synchronized (stats) {
15429                    wtime = stats.getProcessWakeTime(app.info.uid,
15430                            app.pid, curRealtime);
15431                }
15432                long wtimeUsed = wtime - app.lastWakeTime;
15433                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15434                if (DEBUG_POWER) {
15435                    StringBuilder sb = new StringBuilder(128);
15436                    sb.append("Wake for ");
15437                    app.toShortString(sb);
15438                    sb.append(": over ");
15439                    TimeUtils.formatDuration(realtimeSince, sb);
15440                    sb.append(" used ");
15441                    TimeUtils.formatDuration(wtimeUsed, sb);
15442                    sb.append(" (");
15443                    sb.append((wtimeUsed*100)/realtimeSince);
15444                    sb.append("%)");
15445                    Slog.i(TAG, sb.toString());
15446                    sb.setLength(0);
15447                    sb.append("CPU for ");
15448                    app.toShortString(sb);
15449                    sb.append(": over ");
15450                    TimeUtils.formatDuration(uptimeSince, sb);
15451                    sb.append(" used ");
15452                    TimeUtils.formatDuration(cputimeUsed, sb);
15453                    sb.append(" (");
15454                    sb.append((cputimeUsed*100)/uptimeSince);
15455                    sb.append("%)");
15456                    Slog.i(TAG, sb.toString());
15457                }
15458                // If a process has held a wake lock for more
15459                // than 50% of the time during this period,
15460                // that sounds bad.  Kill!
15461                if (doWakeKills && realtimeSince > 0
15462                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15463                    synchronized (stats) {
15464                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15465                                realtimeSince, wtimeUsed);
15466                    }
15467                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15468                            + " during " + realtimeSince);
15469                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15470                } else if (doCpuKills && uptimeSince > 0
15471                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15472                    synchronized (stats) {
15473                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15474                                uptimeSince, cputimeUsed);
15475                    }
15476                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15477                            + " during " + uptimeSince);
15478                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15479                } else {
15480                    app.lastWakeTime = wtime;
15481                    app.lastCpuTime = app.curCpuTime;
15482                }
15483            }
15484        }
15485    }
15486
15487    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15488            ProcessRecord TOP_APP, boolean doingAll, long now) {
15489        boolean success = true;
15490
15491        if (app.curRawAdj != app.setRawAdj) {
15492            if (wasKeeping && !app.keeping) {
15493                // This app is no longer something we want to keep.  Note
15494                // its current wake lock time to later know to kill it if
15495                // it is not behaving well.
15496                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15497                synchronized (stats) {
15498                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15499                            app.pid, SystemClock.elapsedRealtime());
15500                }
15501                app.lastCpuTime = app.curCpuTime;
15502            }
15503
15504            app.setRawAdj = app.curRawAdj;
15505        }
15506
15507        int changes = 0;
15508
15509        if (app.curAdj != app.setAdj) {
15510            ProcessList.setOomAdj(app.pid, app.curAdj);
15511            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15512                TAG, "Set " + app.pid + " " + app.processName +
15513                " adj " + app.curAdj + ": " + app.adjType);
15514            app.setAdj = app.curAdj;
15515        }
15516
15517        if (app.setSchedGroup != app.curSchedGroup) {
15518            app.setSchedGroup = app.curSchedGroup;
15519            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15520                    "Setting process group of " + app.processName
15521                    + " to " + app.curSchedGroup);
15522            if (app.waitingToKill != null &&
15523                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15524                killUnneededProcessLocked(app, app.waitingToKill);
15525                success = false;
15526            } else {
15527                if (true) {
15528                    long oldId = Binder.clearCallingIdentity();
15529                    try {
15530                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15531                    } catch (Exception e) {
15532                        Slog.w(TAG, "Failed setting process group of " + app.pid
15533                                + " to " + app.curSchedGroup);
15534                        e.printStackTrace();
15535                    } finally {
15536                        Binder.restoreCallingIdentity(oldId);
15537                    }
15538                } else {
15539                    if (app.thread != null) {
15540                        try {
15541                            app.thread.setSchedulingGroup(app.curSchedGroup);
15542                        } catch (RemoteException e) {
15543                        }
15544                    }
15545                }
15546                Process.setSwappiness(app.pid,
15547                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15548            }
15549        }
15550        if (app.repForegroundActivities != app.foregroundActivities) {
15551            app.repForegroundActivities = app.foregroundActivities;
15552            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15553        }
15554        if (app.repProcState != app.curProcState) {
15555            app.repProcState = app.curProcState;
15556            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15557            if (app.thread != null) {
15558                try {
15559                    if (false) {
15560                        //RuntimeException h = new RuntimeException("here");
15561                        Slog.i(TAG, "Sending new process state " + app.repProcState
15562                                + " to " + app /*, h*/);
15563                    }
15564                    app.thread.setProcessState(app.repProcState);
15565                } catch (RemoteException e) {
15566                }
15567            }
15568        }
15569        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15570                app.setProcState)) {
15571            app.lastStateTime = now;
15572            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15573                    isSleeping(), now);
15574            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15575                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15576                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15577                    + (app.nextPssTime-now) + ": " + app);
15578        } else {
15579            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15580                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15581                requestPssLocked(app, app.setProcState);
15582                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15583                        isSleeping(), now);
15584            } else if (false && DEBUG_PSS) {
15585                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15586            }
15587        }
15588        if (app.setProcState != app.curProcState) {
15589            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15590                    "Proc state change of " + app.processName
15591                    + " to " + app.curProcState);
15592            app.setProcState = app.curProcState;
15593            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15594                app.notCachedSinceIdle = false;
15595            }
15596            if (!doingAll) {
15597                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15598            } else {
15599                app.procStateChanged = true;
15600            }
15601        }
15602
15603        if (changes != 0) {
15604            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15605            int i = mPendingProcessChanges.size()-1;
15606            ProcessChangeItem item = null;
15607            while (i >= 0) {
15608                item = mPendingProcessChanges.get(i);
15609                if (item.pid == app.pid) {
15610                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15611                    break;
15612                }
15613                i--;
15614            }
15615            if (i < 0) {
15616                // No existing item in pending changes; need a new one.
15617                final int NA = mAvailProcessChanges.size();
15618                if (NA > 0) {
15619                    item = mAvailProcessChanges.remove(NA-1);
15620                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15621                } else {
15622                    item = new ProcessChangeItem();
15623                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15624                }
15625                item.changes = 0;
15626                item.pid = app.pid;
15627                item.uid = app.info.uid;
15628                if (mPendingProcessChanges.size() == 0) {
15629                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15630                            "*** Enqueueing dispatch processes changed!");
15631                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15632                }
15633                mPendingProcessChanges.add(item);
15634            }
15635            item.changes |= changes;
15636            item.processState = app.repProcState;
15637            item.foregroundActivities = app.repForegroundActivities;
15638            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15639                    + Integer.toHexString(System.identityHashCode(item))
15640                    + " " + app.toShortString() + ": changes=" + item.changes
15641                    + " procState=" + item.processState
15642                    + " foreground=" + item.foregroundActivities
15643                    + " type=" + app.adjType + " source=" + app.adjSource
15644                    + " target=" + app.adjTarget);
15645        }
15646
15647        return success;
15648    }
15649
15650    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15651        if (proc.thread != null && proc.baseProcessTracker != null) {
15652            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15653        }
15654    }
15655
15656    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15657            ProcessRecord TOP_APP, boolean doingAll, long now) {
15658        if (app.thread == null) {
15659            return false;
15660        }
15661
15662        final boolean wasKeeping = app.keeping;
15663
15664        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15665
15666        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15667    }
15668
15669    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15670            boolean oomAdj) {
15671        if (isForeground != proc.foregroundServices) {
15672            proc.foregroundServices = isForeground;
15673            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15674                    proc.info.uid);
15675            if (isForeground) {
15676                if (curProcs == null) {
15677                    curProcs = new ArrayList<ProcessRecord>();
15678                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15679                }
15680                if (!curProcs.contains(proc)) {
15681                    curProcs.add(proc);
15682                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15683                            proc.info.packageName, proc.info.uid);
15684                }
15685            } else {
15686                if (curProcs != null) {
15687                    if (curProcs.remove(proc)) {
15688                        mBatteryStatsService.noteEvent(
15689                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15690                                proc.info.packageName, proc.info.uid);
15691                        if (curProcs.size() <= 0) {
15692                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15693                        }
15694                    }
15695                }
15696            }
15697            if (oomAdj) {
15698                updateOomAdjLocked();
15699            }
15700        }
15701    }
15702
15703    private final ActivityRecord resumedAppLocked() {
15704        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15705        String pkg;
15706        int uid;
15707        if (act != null && !act.sleeping) {
15708            pkg = act.packageName;
15709            uid = act.info.applicationInfo.uid;
15710        } else {
15711            pkg = null;
15712            uid = -1;
15713        }
15714        // Has the UID or resumed package name changed?
15715        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15716                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15717            if (mCurResumedPackage != null) {
15718                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15719                        mCurResumedPackage, mCurResumedUid);
15720            }
15721            mCurResumedPackage = pkg;
15722            mCurResumedUid = uid;
15723            if (mCurResumedPackage != null) {
15724                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15725                        mCurResumedPackage, mCurResumedUid);
15726            }
15727        }
15728        return act;
15729    }
15730
15731    final boolean updateOomAdjLocked(ProcessRecord app) {
15732        final ActivityRecord TOP_ACT = resumedAppLocked();
15733        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15734        final boolean wasCached = app.cached;
15735
15736        mAdjSeq++;
15737
15738        // This is the desired cached adjusment we want to tell it to use.
15739        // If our app is currently cached, we know it, and that is it.  Otherwise,
15740        // we don't know it yet, and it needs to now be cached we will then
15741        // need to do a complete oom adj.
15742        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15743                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15744        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15745                SystemClock.uptimeMillis());
15746        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15747            // Changed to/from cached state, so apps after it in the LRU
15748            // list may also be changed.
15749            updateOomAdjLocked();
15750        }
15751        return success;
15752    }
15753
15754    final void updateOomAdjLocked() {
15755        final ActivityRecord TOP_ACT = resumedAppLocked();
15756        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15757        final long now = SystemClock.uptimeMillis();
15758        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15759        final int N = mLruProcesses.size();
15760
15761        if (false) {
15762            RuntimeException e = new RuntimeException();
15763            e.fillInStackTrace();
15764            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15765        }
15766
15767        mAdjSeq++;
15768        mNewNumServiceProcs = 0;
15769        mNewNumAServiceProcs = 0;
15770
15771        final int emptyProcessLimit;
15772        final int cachedProcessLimit;
15773        if (mProcessLimit <= 0) {
15774            emptyProcessLimit = cachedProcessLimit = 0;
15775        } else if (mProcessLimit == 1) {
15776            emptyProcessLimit = 1;
15777            cachedProcessLimit = 0;
15778        } else {
15779            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15780            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15781        }
15782
15783        // Let's determine how many processes we have running vs.
15784        // how many slots we have for background processes; we may want
15785        // to put multiple processes in a slot of there are enough of
15786        // them.
15787        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15788                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15789        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15790        if (numEmptyProcs > cachedProcessLimit) {
15791            // If there are more empty processes than our limit on cached
15792            // processes, then use the cached process limit for the factor.
15793            // This ensures that the really old empty processes get pushed
15794            // down to the bottom, so if we are running low on memory we will
15795            // have a better chance at keeping around more cached processes
15796            // instead of a gazillion empty processes.
15797            numEmptyProcs = cachedProcessLimit;
15798        }
15799        int emptyFactor = numEmptyProcs/numSlots;
15800        if (emptyFactor < 1) emptyFactor = 1;
15801        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15802        if (cachedFactor < 1) cachedFactor = 1;
15803        int stepCached = 0;
15804        int stepEmpty = 0;
15805        int numCached = 0;
15806        int numEmpty = 0;
15807        int numTrimming = 0;
15808
15809        mNumNonCachedProcs = 0;
15810        mNumCachedHiddenProcs = 0;
15811
15812        // First update the OOM adjustment for each of the
15813        // application processes based on their current state.
15814        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15815        int nextCachedAdj = curCachedAdj+1;
15816        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15817        int nextEmptyAdj = curEmptyAdj+2;
15818        for (int i=N-1; i>=0; i--) {
15819            ProcessRecord app = mLruProcesses.get(i);
15820            if (!app.killedByAm && app.thread != null) {
15821                app.procStateChanged = false;
15822                final boolean wasKeeping = app.keeping;
15823                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15824
15825                // If we haven't yet assigned the final cached adj
15826                // to the process, do that now.
15827                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15828                    switch (app.curProcState) {
15829                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15830                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15831                            // This process is a cached process holding activities...
15832                            // assign it the next cached value for that type, and then
15833                            // step that cached level.
15834                            app.curRawAdj = curCachedAdj;
15835                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15836                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15837                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15838                                    + ")");
15839                            if (curCachedAdj != nextCachedAdj) {
15840                                stepCached++;
15841                                if (stepCached >= cachedFactor) {
15842                                    stepCached = 0;
15843                                    curCachedAdj = nextCachedAdj;
15844                                    nextCachedAdj += 2;
15845                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15846                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15847                                    }
15848                                }
15849                            }
15850                            break;
15851                        default:
15852                            // For everything else, assign next empty cached process
15853                            // level and bump that up.  Note that this means that
15854                            // long-running services that have dropped down to the
15855                            // cached level will be treated as empty (since their process
15856                            // state is still as a service), which is what we want.
15857                            app.curRawAdj = curEmptyAdj;
15858                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15859                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15860                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15861                                    + ")");
15862                            if (curEmptyAdj != nextEmptyAdj) {
15863                                stepEmpty++;
15864                                if (stepEmpty >= emptyFactor) {
15865                                    stepEmpty = 0;
15866                                    curEmptyAdj = nextEmptyAdj;
15867                                    nextEmptyAdj += 2;
15868                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15869                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15870                                    }
15871                                }
15872                            }
15873                            break;
15874                    }
15875                }
15876
15877                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15878
15879                // Count the number of process types.
15880                switch (app.curProcState) {
15881                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15882                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15883                        mNumCachedHiddenProcs++;
15884                        numCached++;
15885                        if (numCached > cachedProcessLimit) {
15886                            killUnneededProcessLocked(app, "cached #" + numCached);
15887                        }
15888                        break;
15889                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15890                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15891                                && app.lastActivityTime < oldTime) {
15892                            killUnneededProcessLocked(app, "empty for "
15893                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15894                                    / 1000) + "s");
15895                        } else {
15896                            numEmpty++;
15897                            if (numEmpty > emptyProcessLimit) {
15898                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15899                            }
15900                        }
15901                        break;
15902                    default:
15903                        mNumNonCachedProcs++;
15904                        break;
15905                }
15906
15907                if (app.isolated && app.services.size() <= 0) {
15908                    // If this is an isolated process, and there are no
15909                    // services running in it, then the process is no longer
15910                    // needed.  We agressively kill these because we can by
15911                    // definition not re-use the same process again, and it is
15912                    // good to avoid having whatever code was running in them
15913                    // left sitting around after no longer needed.
15914                    killUnneededProcessLocked(app, "isolated not needed");
15915                }
15916
15917                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15918                        && !app.killedByAm) {
15919                    numTrimming++;
15920                }
15921            }
15922        }
15923
15924        mNumServiceProcs = mNewNumServiceProcs;
15925
15926        // Now determine the memory trimming level of background processes.
15927        // Unfortunately we need to start at the back of the list to do this
15928        // properly.  We only do this if the number of background apps we
15929        // are managing to keep around is less than half the maximum we desire;
15930        // if we are keeping a good number around, we'll let them use whatever
15931        // memory they want.
15932        final int numCachedAndEmpty = numCached + numEmpty;
15933        int memFactor;
15934        if (numCached <= ProcessList.TRIM_CACHED_APPS
15935                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15936            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15937                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15938            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15939                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15940            } else {
15941                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15942            }
15943        } else {
15944            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15945        }
15946        // We always allow the memory level to go up (better).  We only allow it to go
15947        // down if we are in a state where that is allowed, *and* the total number of processes
15948        // has gone down since last time.
15949        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15950                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15951                + " last=" + mLastNumProcesses);
15952        if (memFactor > mLastMemoryLevel) {
15953            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15954                memFactor = mLastMemoryLevel;
15955                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15956            }
15957        }
15958        mLastMemoryLevel = memFactor;
15959        mLastNumProcesses = mLruProcesses.size();
15960        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15961        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15962        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15963            if (mLowRamStartTime == 0) {
15964                mLowRamStartTime = now;
15965            }
15966            int step = 0;
15967            int fgTrimLevel;
15968            switch (memFactor) {
15969                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15970                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15971                    break;
15972                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15973                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15974                    break;
15975                default:
15976                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15977                    break;
15978            }
15979            int factor = numTrimming/3;
15980            int minFactor = 2;
15981            if (mHomeProcess != null) minFactor++;
15982            if (mPreviousProcess != null) minFactor++;
15983            if (factor < minFactor) factor = minFactor;
15984            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15985            for (int i=N-1; i>=0; i--) {
15986                ProcessRecord app = mLruProcesses.get(i);
15987                if (allChanged || app.procStateChanged) {
15988                    setProcessTrackerState(app, trackerMemFactor, now);
15989                    app.procStateChanged = false;
15990                }
15991                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15992                        && !app.killedByAm) {
15993                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15994                        try {
15995                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15996                                    "Trimming memory of " + app.processName
15997                                    + " to " + curLevel);
15998                            app.thread.scheduleTrimMemory(curLevel);
15999                        } catch (RemoteException e) {
16000                        }
16001                        if (false) {
16002                            // For now we won't do this; our memory trimming seems
16003                            // to be good enough at this point that destroying
16004                            // activities causes more harm than good.
16005                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16006                                    && app != mHomeProcess && app != mPreviousProcess) {
16007                                // Need to do this on its own message because the stack may not
16008                                // be in a consistent state at this point.
16009                                // For these apps we will also finish their activities
16010                                // to help them free memory.
16011                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16012                            }
16013                        }
16014                    }
16015                    app.trimMemoryLevel = curLevel;
16016                    step++;
16017                    if (step >= factor) {
16018                        step = 0;
16019                        switch (curLevel) {
16020                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16021                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16022                                break;
16023                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16024                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16025                                break;
16026                        }
16027                    }
16028                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16029                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16030                            && app.thread != null) {
16031                        try {
16032                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16033                                    "Trimming memory of heavy-weight " + app.processName
16034                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16035                            app.thread.scheduleTrimMemory(
16036                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16037                        } catch (RemoteException e) {
16038                        }
16039                    }
16040                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16041                } else {
16042                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16043                            || app.systemNoUi) && app.pendingUiClean) {
16044                        // If this application is now in the background and it
16045                        // had done UI, then give it the special trim level to
16046                        // have it free UI resources.
16047                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16048                        if (app.trimMemoryLevel < level && app.thread != null) {
16049                            try {
16050                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16051                                        "Trimming memory of bg-ui " + app.processName
16052                                        + " to " + level);
16053                                app.thread.scheduleTrimMemory(level);
16054                            } catch (RemoteException e) {
16055                            }
16056                        }
16057                        app.pendingUiClean = false;
16058                    }
16059                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16060                        try {
16061                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16062                                    "Trimming memory of fg " + app.processName
16063                                    + " to " + fgTrimLevel);
16064                            app.thread.scheduleTrimMemory(fgTrimLevel);
16065                        } catch (RemoteException e) {
16066                        }
16067                    }
16068                    app.trimMemoryLevel = fgTrimLevel;
16069                }
16070            }
16071        } else {
16072            if (mLowRamStartTime != 0) {
16073                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16074                mLowRamStartTime = 0;
16075            }
16076            for (int i=N-1; i>=0; i--) {
16077                ProcessRecord app = mLruProcesses.get(i);
16078                if (allChanged || app.procStateChanged) {
16079                    setProcessTrackerState(app, trackerMemFactor, now);
16080                    app.procStateChanged = false;
16081                }
16082                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16083                        || app.systemNoUi) && app.pendingUiClean) {
16084                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16085                            && app.thread != null) {
16086                        try {
16087                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16088                                    "Trimming memory of ui hidden " + app.processName
16089                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16090                            app.thread.scheduleTrimMemory(
16091                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16092                        } catch (RemoteException e) {
16093                        }
16094                    }
16095                    app.pendingUiClean = false;
16096                }
16097                app.trimMemoryLevel = 0;
16098            }
16099        }
16100
16101        if (mAlwaysFinishActivities) {
16102            // Need to do this on its own message because the stack may not
16103            // be in a consistent state at this point.
16104            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16105        }
16106
16107        if (allChanged) {
16108            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16109        }
16110
16111        if (mProcessStats.shouldWriteNowLocked(now)) {
16112            mHandler.post(new Runnable() {
16113                @Override public void run() {
16114                    synchronized (ActivityManagerService.this) {
16115                        mProcessStats.writeStateAsyncLocked();
16116                    }
16117                }
16118            });
16119        }
16120
16121        if (DEBUG_OOM_ADJ) {
16122            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16123        }
16124    }
16125
16126    final void trimApplications() {
16127        synchronized (this) {
16128            int i;
16129
16130            // First remove any unused application processes whose package
16131            // has been removed.
16132            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16133                final ProcessRecord app = mRemovedProcesses.get(i);
16134                if (app.activities.size() == 0
16135                        && app.curReceiver == null && app.services.size() == 0) {
16136                    Slog.i(
16137                        TAG, "Exiting empty application process "
16138                        + app.processName + " ("
16139                        + (app.thread != null ? app.thread.asBinder() : null)
16140                        + ")\n");
16141                    if (app.pid > 0 && app.pid != MY_PID) {
16142                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16143                                app.processName, app.setAdj, "empty");
16144                        app.killedByAm = true;
16145                        Process.killProcessQuiet(app.pid);
16146                    } else {
16147                        try {
16148                            app.thread.scheduleExit();
16149                        } catch (Exception e) {
16150                            // Ignore exceptions.
16151                        }
16152                    }
16153                    cleanUpApplicationRecordLocked(app, false, true, -1);
16154                    mRemovedProcesses.remove(i);
16155
16156                    if (app.persistent) {
16157                        if (app.persistent) {
16158                            addAppLocked(app.info, false);
16159                        }
16160                    }
16161                }
16162            }
16163
16164            // Now update the oom adj for all processes.
16165            updateOomAdjLocked();
16166        }
16167    }
16168
16169    /** This method sends the specified signal to each of the persistent apps */
16170    public void signalPersistentProcesses(int sig) throws RemoteException {
16171        if (sig != Process.SIGNAL_USR1) {
16172            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16173        }
16174
16175        synchronized (this) {
16176            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16177                    != PackageManager.PERMISSION_GRANTED) {
16178                throw new SecurityException("Requires permission "
16179                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16180            }
16181
16182            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16183                ProcessRecord r = mLruProcesses.get(i);
16184                if (r.thread != null && r.persistent) {
16185                    Process.sendSignal(r.pid, sig);
16186                }
16187            }
16188        }
16189    }
16190
16191    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16192        if (proc == null || proc == mProfileProc) {
16193            proc = mProfileProc;
16194            path = mProfileFile;
16195            profileType = mProfileType;
16196            clearProfilerLocked();
16197        }
16198        if (proc == null) {
16199            return;
16200        }
16201        try {
16202            proc.thread.profilerControl(false, path, null, profileType);
16203        } catch (RemoteException e) {
16204            throw new IllegalStateException("Process disappeared");
16205        }
16206    }
16207
16208    private void clearProfilerLocked() {
16209        if (mProfileFd != null) {
16210            try {
16211                mProfileFd.close();
16212            } catch (IOException e) {
16213            }
16214        }
16215        mProfileApp = null;
16216        mProfileProc = null;
16217        mProfileFile = null;
16218        mProfileType = 0;
16219        mAutoStopProfiler = false;
16220    }
16221
16222    public boolean profileControl(String process, int userId, boolean start,
16223            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16224
16225        try {
16226            synchronized (this) {
16227                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16228                // its own permission.
16229                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16230                        != PackageManager.PERMISSION_GRANTED) {
16231                    throw new SecurityException("Requires permission "
16232                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16233                }
16234
16235                if (start && fd == null) {
16236                    throw new IllegalArgumentException("null fd");
16237                }
16238
16239                ProcessRecord proc = null;
16240                if (process != null) {
16241                    proc = findProcessLocked(process, userId, "profileControl");
16242                }
16243
16244                if (start && (proc == null || proc.thread == null)) {
16245                    throw new IllegalArgumentException("Unknown process: " + process);
16246                }
16247
16248                if (start) {
16249                    stopProfilerLocked(null, null, 0);
16250                    setProfileApp(proc.info, proc.processName, path, fd, false);
16251                    mProfileProc = proc;
16252                    mProfileType = profileType;
16253                    try {
16254                        fd = fd.dup();
16255                    } catch (IOException e) {
16256                        fd = null;
16257                    }
16258                    proc.thread.profilerControl(start, path, fd, profileType);
16259                    fd = null;
16260                    mProfileFd = null;
16261                } else {
16262                    stopProfilerLocked(proc, path, profileType);
16263                    if (fd != null) {
16264                        try {
16265                            fd.close();
16266                        } catch (IOException e) {
16267                        }
16268                    }
16269                }
16270
16271                return true;
16272            }
16273        } catch (RemoteException e) {
16274            throw new IllegalStateException("Process disappeared");
16275        } finally {
16276            if (fd != null) {
16277                try {
16278                    fd.close();
16279                } catch (IOException e) {
16280                }
16281            }
16282        }
16283    }
16284
16285    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16286        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16287                userId, true, true, callName, null);
16288        ProcessRecord proc = null;
16289        try {
16290            int pid = Integer.parseInt(process);
16291            synchronized (mPidsSelfLocked) {
16292                proc = mPidsSelfLocked.get(pid);
16293            }
16294        } catch (NumberFormatException e) {
16295        }
16296
16297        if (proc == null) {
16298            ArrayMap<String, SparseArray<ProcessRecord>> all
16299                    = mProcessNames.getMap();
16300            SparseArray<ProcessRecord> procs = all.get(process);
16301            if (procs != null && procs.size() > 0) {
16302                proc = procs.valueAt(0);
16303                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16304                    for (int i=1; i<procs.size(); i++) {
16305                        ProcessRecord thisProc = procs.valueAt(i);
16306                        if (thisProc.userId == userId) {
16307                            proc = thisProc;
16308                            break;
16309                        }
16310                    }
16311                }
16312            }
16313        }
16314
16315        return proc;
16316    }
16317
16318    public boolean dumpHeap(String process, int userId, boolean managed,
16319            String path, ParcelFileDescriptor fd) throws RemoteException {
16320
16321        try {
16322            synchronized (this) {
16323                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16324                // its own permission (same as profileControl).
16325                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16326                        != PackageManager.PERMISSION_GRANTED) {
16327                    throw new SecurityException("Requires permission "
16328                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16329                }
16330
16331                if (fd == null) {
16332                    throw new IllegalArgumentException("null fd");
16333                }
16334
16335                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16336                if (proc == null || proc.thread == null) {
16337                    throw new IllegalArgumentException("Unknown process: " + process);
16338                }
16339
16340                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16341                if (!isDebuggable) {
16342                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16343                        throw new SecurityException("Process not debuggable: " + proc);
16344                    }
16345                }
16346
16347                proc.thread.dumpHeap(managed, path, fd);
16348                fd = null;
16349                return true;
16350            }
16351        } catch (RemoteException e) {
16352            throw new IllegalStateException("Process disappeared");
16353        } finally {
16354            if (fd != null) {
16355                try {
16356                    fd.close();
16357                } catch (IOException e) {
16358                }
16359            }
16360        }
16361    }
16362
16363    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16364    public void monitor() {
16365        synchronized (this) { }
16366    }
16367
16368    void onCoreSettingsChange(Bundle settings) {
16369        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16370            ProcessRecord processRecord = mLruProcesses.get(i);
16371            try {
16372                if (processRecord.thread != null) {
16373                    processRecord.thread.setCoreSettings(settings);
16374                }
16375            } catch (RemoteException re) {
16376                /* ignore */
16377            }
16378        }
16379    }
16380
16381    // Multi-user methods
16382
16383    /**
16384     * Start user, if its not already running, but don't bring it to foreground.
16385     */
16386    @Override
16387    public boolean startUserInBackground(final int userId) {
16388        return startUser(userId, /* foreground */ false);
16389    }
16390
16391    /**
16392     * Refreshes the list of users related to the current user when either a
16393     * user switch happens or when a new related user is started in the
16394     * background.
16395     */
16396    private void updateCurrentProfileIdsLocked() {
16397        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16398                mCurrentUserId, false /* enabledOnly */);
16399        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16400        for (int i = 0; i < currentProfileIds.length; i++) {
16401            currentProfileIds[i] = profiles.get(i).id;
16402        }
16403        mCurrentProfileIds = currentProfileIds;
16404    }
16405
16406    private Set getProfileIdsLocked(int userId) {
16407        Set userIds = new HashSet<Integer>();
16408        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16409                userId, false /* enabledOnly */);
16410        for (UserInfo user : profiles) {
16411            userIds.add(Integer.valueOf(user.id));
16412        }
16413        return userIds;
16414    }
16415
16416    @Override
16417    public boolean switchUser(final int userId) {
16418        return startUser(userId, /* foregound */ true);
16419    }
16420
16421    private boolean startUser(final int userId, boolean foreground) {
16422        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16423                != PackageManager.PERMISSION_GRANTED) {
16424            String msg = "Permission Denial: switchUser() from pid="
16425                    + Binder.getCallingPid()
16426                    + ", uid=" + Binder.getCallingUid()
16427                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16428            Slog.w(TAG, msg);
16429            throw new SecurityException(msg);
16430        }
16431
16432        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16433
16434        final long ident = Binder.clearCallingIdentity();
16435        try {
16436            synchronized (this) {
16437                final int oldUserId = mCurrentUserId;
16438                if (oldUserId == userId) {
16439                    return true;
16440                }
16441
16442                mStackSupervisor.setLockTaskModeLocked(null);
16443
16444                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16445                if (userInfo == null) {
16446                    Slog.w(TAG, "No user info for user #" + userId);
16447                    return false;
16448                }
16449
16450                if (foreground) {
16451                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16452                            R.anim.screen_user_enter);
16453                }
16454
16455                boolean needStart = false;
16456
16457                // If the user we are switching to is not currently started, then
16458                // we need to start it now.
16459                if (mStartedUsers.get(userId) == null) {
16460                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16461                    updateStartedUserArrayLocked();
16462                    needStart = true;
16463                }
16464
16465                final Integer userIdInt = Integer.valueOf(userId);
16466                mUserLru.remove(userIdInt);
16467                mUserLru.add(userIdInt);
16468
16469                if (foreground) {
16470                    mCurrentUserId = userId;
16471                    updateCurrentProfileIdsLocked();
16472                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16473                    // Once the internal notion of the active user has switched, we lock the device
16474                    // with the option to show the user switcher on the keyguard.
16475                    mWindowManager.lockNow(null);
16476                } else {
16477                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16478                    updateCurrentProfileIdsLocked();
16479                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16480                    mUserLru.remove(currentUserIdInt);
16481                    mUserLru.add(currentUserIdInt);
16482                }
16483
16484                final UserStartedState uss = mStartedUsers.get(userId);
16485
16486                // Make sure user is in the started state.  If it is currently
16487                // stopping, we need to knock that off.
16488                if (uss.mState == UserStartedState.STATE_STOPPING) {
16489                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16490                    // so we can just fairly silently bring the user back from
16491                    // the almost-dead.
16492                    uss.mState = UserStartedState.STATE_RUNNING;
16493                    updateStartedUserArrayLocked();
16494                    needStart = true;
16495                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16496                    // This means ACTION_SHUTDOWN has been sent, so we will
16497                    // need to treat this as a new boot of the user.
16498                    uss.mState = UserStartedState.STATE_BOOTING;
16499                    updateStartedUserArrayLocked();
16500                    needStart = true;
16501                }
16502
16503                if (uss.mState == UserStartedState.STATE_BOOTING) {
16504                    // Booting up a new user, need to tell system services about it.
16505                    // Note that this is on the same handler as scheduling of broadcasts,
16506                    // which is important because it needs to go first.
16507                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16508                }
16509
16510                if (foreground) {
16511                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16512                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16513                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16514                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16515                            oldUserId, userId, uss));
16516                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16517                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16518                }
16519
16520                if (needStart) {
16521                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16522                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16523                            | Intent.FLAG_RECEIVER_FOREGROUND);
16524                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16525                    broadcastIntentLocked(null, null, intent,
16526                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16527                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16528                }
16529
16530                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16531                    if (userId != 0) {
16532                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16533                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16534                        broadcastIntentLocked(null, null, intent, null,
16535                                new IIntentReceiver.Stub() {
16536                                    public void performReceive(Intent intent, int resultCode,
16537                                            String data, Bundle extras, boolean ordered,
16538                                            boolean sticky, int sendingUser) {
16539                                        userInitialized(uss, userId);
16540                                    }
16541                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16542                                true, false, MY_PID, Process.SYSTEM_UID,
16543                                userId);
16544                        uss.initializing = true;
16545                    } else {
16546                        getUserManagerLocked().makeInitialized(userInfo.id);
16547                    }
16548                }
16549
16550                if (foreground) {
16551                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16552                    if (homeInFront) {
16553                        startHomeActivityLocked(userId);
16554                    } else {
16555                        mStackSupervisor.resumeTopActivitiesLocked();
16556                    }
16557                    EventLogTags.writeAmSwitchUser(userId);
16558                    getUserManagerLocked().userForeground(userId);
16559                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16560                }
16561
16562                if (needStart) {
16563                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16564                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16565                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16566                    broadcastIntentLocked(null, null, intent,
16567                            null, new IIntentReceiver.Stub() {
16568                                @Override
16569                                public void performReceive(Intent intent, int resultCode, String data,
16570                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16571                                        throws RemoteException {
16572                                }
16573                            }, 0, null, null,
16574                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16575                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16576                }
16577            }
16578        } finally {
16579            Binder.restoreCallingIdentity(ident);
16580        }
16581
16582        return true;
16583    }
16584
16585    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16586        long ident = Binder.clearCallingIdentity();
16587        try {
16588            Intent intent;
16589            if (oldUserId >= 0) {
16590                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16591                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16592                        | Intent.FLAG_RECEIVER_FOREGROUND);
16593                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16594                broadcastIntentLocked(null, null, intent,
16595                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16596                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16597            }
16598            if (newUserId >= 0) {
16599                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16600                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16601                        | Intent.FLAG_RECEIVER_FOREGROUND);
16602                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16603                broadcastIntentLocked(null, null, intent,
16604                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16605                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16606                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16607                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16608                        | Intent.FLAG_RECEIVER_FOREGROUND);
16609                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16610                broadcastIntentLocked(null, null, intent,
16611                        null, null, 0, null, null,
16612                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16613                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16614            }
16615        } finally {
16616            Binder.restoreCallingIdentity(ident);
16617        }
16618    }
16619
16620    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16621            final int newUserId) {
16622        final int N = mUserSwitchObservers.beginBroadcast();
16623        if (N > 0) {
16624            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16625                int mCount = 0;
16626                @Override
16627                public void sendResult(Bundle data) throws RemoteException {
16628                    synchronized (ActivityManagerService.this) {
16629                        if (mCurUserSwitchCallback == this) {
16630                            mCount++;
16631                            if (mCount == N) {
16632                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16633                            }
16634                        }
16635                    }
16636                }
16637            };
16638            synchronized (this) {
16639                uss.switching = true;
16640                mCurUserSwitchCallback = callback;
16641            }
16642            for (int i=0; i<N; i++) {
16643                try {
16644                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16645                            newUserId, callback);
16646                } catch (RemoteException e) {
16647                }
16648            }
16649        } else {
16650            synchronized (this) {
16651                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16652            }
16653        }
16654        mUserSwitchObservers.finishBroadcast();
16655    }
16656
16657    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16658        synchronized (this) {
16659            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16660            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16661        }
16662    }
16663
16664    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16665        mCurUserSwitchCallback = null;
16666        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16667        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16668                oldUserId, newUserId, uss));
16669    }
16670
16671    void userInitialized(UserStartedState uss, int newUserId) {
16672        completeSwitchAndInitalize(uss, newUserId, true, false);
16673    }
16674
16675    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16676        completeSwitchAndInitalize(uss, newUserId, false, true);
16677    }
16678
16679    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16680            boolean clearInitializing, boolean clearSwitching) {
16681        boolean unfrozen = false;
16682        synchronized (this) {
16683            if (clearInitializing) {
16684                uss.initializing = false;
16685                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16686            }
16687            if (clearSwitching) {
16688                uss.switching = false;
16689            }
16690            if (!uss.switching && !uss.initializing) {
16691                mWindowManager.stopFreezingScreen();
16692                unfrozen = true;
16693            }
16694        }
16695        if (unfrozen) {
16696            final int N = mUserSwitchObservers.beginBroadcast();
16697            for (int i=0; i<N; i++) {
16698                try {
16699                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16700                } catch (RemoteException e) {
16701                }
16702            }
16703            mUserSwitchObservers.finishBroadcast();
16704        }
16705    }
16706
16707    void scheduleStartProfilesLocked() {
16708        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16709            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16710                    DateUtils.SECOND_IN_MILLIS);
16711        }
16712    }
16713
16714    void startProfilesLocked() {
16715        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16716        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16717                mCurrentUserId, false /* enabledOnly */);
16718        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16719        for (UserInfo user : profiles) {
16720            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16721                    && user.id != mCurrentUserId) {
16722                toStart.add(user);
16723            }
16724        }
16725        final int n = toStart.size();
16726        int i = 0;
16727        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16728            startUserInBackground(toStart.get(i).id);
16729        }
16730        if (i < n) {
16731            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16732        }
16733    }
16734
16735    void finishUserSwitch(UserStartedState uss) {
16736        synchronized (this) {
16737            if (uss.mState == UserStartedState.STATE_BOOTING
16738                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16739                uss.mState = UserStartedState.STATE_RUNNING;
16740                final int userId = uss.mHandle.getIdentifier();
16741                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16742                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16743                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16744                broadcastIntentLocked(null, null, intent,
16745                        null, null, 0, null, null,
16746                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16747                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16748            }
16749
16750            startProfilesLocked();
16751
16752            int num = mUserLru.size();
16753            int i = 0;
16754            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16755                Integer oldUserId = mUserLru.get(i);
16756                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16757                if (oldUss == null) {
16758                    // Shouldn't happen, but be sane if it does.
16759                    mUserLru.remove(i);
16760                    num--;
16761                    continue;
16762                }
16763                if (oldUss.mState == UserStartedState.STATE_STOPPING
16764                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16765                    // This user is already stopping, doesn't count.
16766                    num--;
16767                    i++;
16768                    continue;
16769                }
16770                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16771                    // Owner and current can't be stopped, but count as running.
16772                    i++;
16773                    continue;
16774                }
16775                // This is a user to be stopped.
16776                stopUserLocked(oldUserId, null);
16777                num--;
16778                i++;
16779            }
16780        }
16781    }
16782
16783    @Override
16784    public int stopUser(final int userId, final IStopUserCallback callback) {
16785        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16786                != PackageManager.PERMISSION_GRANTED) {
16787            String msg = "Permission Denial: switchUser() from pid="
16788                    + Binder.getCallingPid()
16789                    + ", uid=" + Binder.getCallingUid()
16790                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16791            Slog.w(TAG, msg);
16792            throw new SecurityException(msg);
16793        }
16794        if (userId <= 0) {
16795            throw new IllegalArgumentException("Can't stop primary user " + userId);
16796        }
16797        synchronized (this) {
16798            return stopUserLocked(userId, callback);
16799        }
16800    }
16801
16802    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16803        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16804        if (mCurrentUserId == userId) {
16805            return ActivityManager.USER_OP_IS_CURRENT;
16806        }
16807
16808        final UserStartedState uss = mStartedUsers.get(userId);
16809        if (uss == null) {
16810            // User is not started, nothing to do...  but we do need to
16811            // callback if requested.
16812            if (callback != null) {
16813                mHandler.post(new Runnable() {
16814                    @Override
16815                    public void run() {
16816                        try {
16817                            callback.userStopped(userId);
16818                        } catch (RemoteException e) {
16819                        }
16820                    }
16821                });
16822            }
16823            return ActivityManager.USER_OP_SUCCESS;
16824        }
16825
16826        if (callback != null) {
16827            uss.mStopCallbacks.add(callback);
16828        }
16829
16830        if (uss.mState != UserStartedState.STATE_STOPPING
16831                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16832            uss.mState = UserStartedState.STATE_STOPPING;
16833            updateStartedUserArrayLocked();
16834
16835            long ident = Binder.clearCallingIdentity();
16836            try {
16837                // We are going to broadcast ACTION_USER_STOPPING and then
16838                // once that is done send a final ACTION_SHUTDOWN and then
16839                // stop the user.
16840                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16841                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16842                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16843                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16844                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16845                // This is the result receiver for the final shutdown broadcast.
16846                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16847                    @Override
16848                    public void performReceive(Intent intent, int resultCode, String data,
16849                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16850                        finishUserStop(uss);
16851                    }
16852                };
16853                // This is the result receiver for the initial stopping broadcast.
16854                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16855                    @Override
16856                    public void performReceive(Intent intent, int resultCode, String data,
16857                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16858                        // On to the next.
16859                        synchronized (ActivityManagerService.this) {
16860                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16861                                // Whoops, we are being started back up.  Abort, abort!
16862                                return;
16863                            }
16864                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16865                        }
16866                        mSystemServiceManager.stopUser(userId);
16867                        broadcastIntentLocked(null, null, shutdownIntent,
16868                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16869                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16870                    }
16871                };
16872                // Kick things off.
16873                broadcastIntentLocked(null, null, stoppingIntent,
16874                        null, stoppingReceiver, 0, null, null,
16875                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16876                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16877            } finally {
16878                Binder.restoreCallingIdentity(ident);
16879            }
16880        }
16881
16882        return ActivityManager.USER_OP_SUCCESS;
16883    }
16884
16885    void finishUserStop(UserStartedState uss) {
16886        final int userId = uss.mHandle.getIdentifier();
16887        boolean stopped;
16888        ArrayList<IStopUserCallback> callbacks;
16889        synchronized (this) {
16890            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16891            if (mStartedUsers.get(userId) != uss) {
16892                stopped = false;
16893            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16894                stopped = false;
16895            } else {
16896                stopped = true;
16897                // User can no longer run.
16898                mStartedUsers.remove(userId);
16899                mUserLru.remove(Integer.valueOf(userId));
16900                updateStartedUserArrayLocked();
16901
16902                // Clean up all state and processes associated with the user.
16903                // Kill all the processes for the user.
16904                forceStopUserLocked(userId, "finish user");
16905            }
16906        }
16907
16908        for (int i=0; i<callbacks.size(); i++) {
16909            try {
16910                if (stopped) callbacks.get(i).userStopped(userId);
16911                else callbacks.get(i).userStopAborted(userId);
16912            } catch (RemoteException e) {
16913            }
16914        }
16915
16916        if (stopped) {
16917            mSystemServiceManager.cleanupUser(userId);
16918            synchronized (this) {
16919                mStackSupervisor.removeUserLocked(userId);
16920            }
16921        }
16922    }
16923
16924    @Override
16925    public UserInfo getCurrentUser() {
16926        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16927                != PackageManager.PERMISSION_GRANTED) && (
16928                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16929                != PackageManager.PERMISSION_GRANTED)) {
16930            String msg = "Permission Denial: getCurrentUser() from pid="
16931                    + Binder.getCallingPid()
16932                    + ", uid=" + Binder.getCallingUid()
16933                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16934            Slog.w(TAG, msg);
16935            throw new SecurityException(msg);
16936        }
16937        synchronized (this) {
16938            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16939        }
16940    }
16941
16942    int getCurrentUserIdLocked() {
16943        return mCurrentUserId;
16944    }
16945
16946    @Override
16947    public boolean isUserRunning(int userId, boolean orStopped) {
16948        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16949                != PackageManager.PERMISSION_GRANTED) {
16950            String msg = "Permission Denial: isUserRunning() from pid="
16951                    + Binder.getCallingPid()
16952                    + ", uid=" + Binder.getCallingUid()
16953                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16954            Slog.w(TAG, msg);
16955            throw new SecurityException(msg);
16956        }
16957        synchronized (this) {
16958            return isUserRunningLocked(userId, orStopped);
16959        }
16960    }
16961
16962    boolean isUserRunningLocked(int userId, boolean orStopped) {
16963        UserStartedState state = mStartedUsers.get(userId);
16964        if (state == null) {
16965            return false;
16966        }
16967        if (orStopped) {
16968            return true;
16969        }
16970        return state.mState != UserStartedState.STATE_STOPPING
16971                && state.mState != UserStartedState.STATE_SHUTDOWN;
16972    }
16973
16974    @Override
16975    public int[] getRunningUserIds() {
16976        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16977                != PackageManager.PERMISSION_GRANTED) {
16978            String msg = "Permission Denial: isUserRunning() from pid="
16979                    + Binder.getCallingPid()
16980                    + ", uid=" + Binder.getCallingUid()
16981                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16982            Slog.w(TAG, msg);
16983            throw new SecurityException(msg);
16984        }
16985        synchronized (this) {
16986            return mStartedUserArray;
16987        }
16988    }
16989
16990    private void updateStartedUserArrayLocked() {
16991        int num = 0;
16992        for (int i=0; i<mStartedUsers.size();  i++) {
16993            UserStartedState uss = mStartedUsers.valueAt(i);
16994            // This list does not include stopping users.
16995            if (uss.mState != UserStartedState.STATE_STOPPING
16996                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16997                num++;
16998            }
16999        }
17000        mStartedUserArray = new int[num];
17001        num = 0;
17002        for (int i=0; i<mStartedUsers.size();  i++) {
17003            UserStartedState uss = mStartedUsers.valueAt(i);
17004            if (uss.mState != UserStartedState.STATE_STOPPING
17005                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17006                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17007                num++;
17008            }
17009        }
17010    }
17011
17012    @Override
17013    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17014        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17015                != PackageManager.PERMISSION_GRANTED) {
17016            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17017                    + Binder.getCallingPid()
17018                    + ", uid=" + Binder.getCallingUid()
17019                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17020            Slog.w(TAG, msg);
17021            throw new SecurityException(msg);
17022        }
17023
17024        mUserSwitchObservers.register(observer);
17025    }
17026
17027    @Override
17028    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17029        mUserSwitchObservers.unregister(observer);
17030    }
17031
17032    private boolean userExists(int userId) {
17033        if (userId == 0) {
17034            return true;
17035        }
17036        UserManagerService ums = getUserManagerLocked();
17037        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17038    }
17039
17040    int[] getUsersLocked() {
17041        UserManagerService ums = getUserManagerLocked();
17042        return ums != null ? ums.getUserIds() : new int[] { 0 };
17043    }
17044
17045    UserManagerService getUserManagerLocked() {
17046        if (mUserManager == null) {
17047            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17048            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17049        }
17050        return mUserManager;
17051    }
17052
17053    private int applyUserId(int uid, int userId) {
17054        return UserHandle.getUid(userId, uid);
17055    }
17056
17057    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17058        if (info == null) return null;
17059        ApplicationInfo newInfo = new ApplicationInfo(info);
17060        newInfo.uid = applyUserId(info.uid, userId);
17061        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17062                + info.packageName;
17063        return newInfo;
17064    }
17065
17066    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17067        if (aInfo == null
17068                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17069            return aInfo;
17070        }
17071
17072        ActivityInfo info = new ActivityInfo(aInfo);
17073        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17074        return info;
17075    }
17076
17077    private final class LocalService extends ActivityManagerInternal {
17078        @Override
17079        public void goingToSleep() {
17080            ActivityManagerService.this.goingToSleep();
17081        }
17082
17083        @Override
17084        public void wakingUp() {
17085            ActivityManagerService.this.wakingUp();
17086        }
17087    }
17088}
17089