ActivityManagerService.java revision 03a9baedc9b933bb6a550c0cb84649b1b45b872c
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            final PackageManager pm = mContext.getPackageManager();
1854            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1855                    new ArrayList<Pair<Intent, Integer>>();
1856            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1857            // Copy the list of recent tasks so that we don't hold onto the lock on
1858            // ActivityManagerService for long periods while checking if components exist.
1859            synchronized (ActivityManagerService.this) {
1860                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1861                    TaskRecord tr = mRecentTasks.get(i);
1862                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1863                }
1864            }
1865            // Check the recent tasks and filter out all tasks with components that no longer exist.
1866            Intent tmpI = new Intent();
1867            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1868                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1869                ComponentName cn = p.first.getComponent();
1870                if (cn != null && cn.getPackageName().equals(packageName)) {
1871                    try {
1872                        // Add the task to the list to remove if the component no longer exists
1873                        tmpI.setComponent(cn);
1874                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1875                            tasksToRemove.add(p.second);
1876                        }
1877                    } catch (Exception e) {}
1878                }
1879            }
1880            // Prune all the tasks with removed components from the list of recent tasks
1881            synchronized (ActivityManagerService.this) {
1882                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1883                    // Remove the task but don't kill the process (since other components in that
1884                    // package may still be running and in the background)
1885                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1886                }
1887            }
1888            return true;
1889        }
1890
1891        @Override
1892        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1893            // Force stop the specified packages
1894            if (packages != null) {
1895                for (String pkg : packages) {
1896                    synchronized (ActivityManagerService.this) {
1897                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1898                                "finished booting")) {
1899                            return true;
1900                        }
1901                    }
1902                }
1903            }
1904            return false;
1905        }
1906    };
1907
1908    public void setSystemProcess() {
1909        try {
1910            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1911            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1912            ServiceManager.addService("meminfo", new MemBinder(this));
1913            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1914            ServiceManager.addService("dbinfo", new DbBinder(this));
1915            if (MONITOR_CPU_USAGE) {
1916                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1917            }
1918            ServiceManager.addService("permission", new PermissionController(this));
1919
1920            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1921                    "android", STOCK_PM_FLAGS);
1922            mSystemThread.installSystemApplicationInfo(info);
1923
1924            synchronized (this) {
1925                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1926                app.persistent = true;
1927                app.pid = MY_PID;
1928                app.maxAdj = ProcessList.SYSTEM_ADJ;
1929                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1930                mProcessNames.put(app.processName, app.uid, app);
1931                synchronized (mPidsSelfLocked) {
1932                    mPidsSelfLocked.put(app.pid, app);
1933                }
1934                updateLruProcessLocked(app, false, null);
1935                updateOomAdjLocked();
1936            }
1937        } catch (PackageManager.NameNotFoundException e) {
1938            throw new RuntimeException(
1939                    "Unable to find android system package", e);
1940        }
1941    }
1942
1943    public void setWindowManager(WindowManagerService wm) {
1944        mWindowManager = wm;
1945        mStackSupervisor.setWindowManager(wm);
1946    }
1947
1948    public void startObservingNativeCrashes() {
1949        final NativeCrashListener ncl = new NativeCrashListener(this);
1950        ncl.start();
1951    }
1952
1953    public IAppOpsService getAppOpsService() {
1954        return mAppOpsService;
1955    }
1956
1957    static class MemBinder extends Binder {
1958        ActivityManagerService mActivityManagerService;
1959        MemBinder(ActivityManagerService activityManagerService) {
1960            mActivityManagerService = activityManagerService;
1961        }
1962
1963        @Override
1964        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1965            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1966                    != PackageManager.PERMISSION_GRANTED) {
1967                pw.println("Permission Denial: can't dump meminfo from from pid="
1968                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1969                        + " without permission " + android.Manifest.permission.DUMP);
1970                return;
1971            }
1972
1973            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1974        }
1975    }
1976
1977    static class GraphicsBinder extends Binder {
1978        ActivityManagerService mActivityManagerService;
1979        GraphicsBinder(ActivityManagerService activityManagerService) {
1980            mActivityManagerService = activityManagerService;
1981        }
1982
1983        @Override
1984        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1985            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1986                    != PackageManager.PERMISSION_GRANTED) {
1987                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1988                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1989                        + " without permission " + android.Manifest.permission.DUMP);
1990                return;
1991            }
1992
1993            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1994        }
1995    }
1996
1997    static class DbBinder extends Binder {
1998        ActivityManagerService mActivityManagerService;
1999        DbBinder(ActivityManagerService activityManagerService) {
2000            mActivityManagerService = activityManagerService;
2001        }
2002
2003        @Override
2004        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2005            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2006                    != PackageManager.PERMISSION_GRANTED) {
2007                pw.println("Permission Denial: can't dump dbinfo from from pid="
2008                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2009                        + " without permission " + android.Manifest.permission.DUMP);
2010                return;
2011            }
2012
2013            mActivityManagerService.dumpDbInfo(fd, pw, args);
2014        }
2015    }
2016
2017    static class CpuBinder extends Binder {
2018        ActivityManagerService mActivityManagerService;
2019        CpuBinder(ActivityManagerService activityManagerService) {
2020            mActivityManagerService = activityManagerService;
2021        }
2022
2023        @Override
2024        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2025            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2026                    != PackageManager.PERMISSION_GRANTED) {
2027                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2028                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2029                        + " without permission " + android.Manifest.permission.DUMP);
2030                return;
2031            }
2032
2033            synchronized (mActivityManagerService.mProcessCpuThread) {
2034                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2035                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2036                        SystemClock.uptimeMillis()));
2037            }
2038        }
2039    }
2040
2041    public static final class Lifecycle extends SystemService {
2042        private final ActivityManagerService mService;
2043
2044        public Lifecycle(Context context) {
2045            super(context);
2046            mService = new ActivityManagerService(context);
2047        }
2048
2049        @Override
2050        public void onStart() {
2051            mService.start();
2052        }
2053
2054        public ActivityManagerService getService() {
2055            return mService;
2056        }
2057    }
2058
2059    // Note: This method is invoked on the main thread but may need to attach various
2060    // handlers to other threads.  So take care to be explicit about the looper.
2061    public ActivityManagerService(Context systemContext) {
2062        mContext = systemContext;
2063        mFactoryTest = FactoryTest.getMode();
2064        mSystemThread = ActivityThread.currentActivityThread();
2065
2066        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2067
2068        mHandlerThread = new ServiceThread(TAG,
2069                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2070        mHandlerThread.start();
2071        mHandler = new MainHandler(mHandlerThread.getLooper());
2072
2073        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2074                "foreground", BROADCAST_FG_TIMEOUT, false);
2075        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2076                "background", BROADCAST_BG_TIMEOUT, true);
2077        mBroadcastQueues[0] = mFgBroadcastQueue;
2078        mBroadcastQueues[1] = mBgBroadcastQueue;
2079
2080        mServices = new ActiveServices(this);
2081        mProviderMap = new ProviderMap(this);
2082
2083        // TODO: Move creation of battery stats service outside of activity manager service.
2084        File dataDir = Environment.getDataDirectory();
2085        File systemDir = new File(dataDir, "system");
2086        systemDir.mkdirs();
2087        mBatteryStatsService = new BatteryStatsService(new File(
2088                systemDir, "batterystats.bin").toString(), mHandler);
2089        mBatteryStatsService.getActiveStatistics().readLocked();
2090        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2091        mOnBattery = DEBUG_POWER ? true
2092                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2093        mBatteryStatsService.getActiveStatistics().setCallback(this);
2094
2095        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2096
2097        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2098        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2099
2100        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2101
2102        // User 0 is the first and only user that runs at boot.
2103        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2104        mUserLru.add(Integer.valueOf(0));
2105        updateStartedUserArrayLocked();
2106
2107        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2108            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2109
2110        mConfiguration.setToDefaults();
2111        mConfiguration.setLocale(Locale.getDefault());
2112
2113        mConfigurationSeq = mConfiguration.seq = 1;
2114        mProcessCpuTracker.init();
2115
2116        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2117        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2118        mStackSupervisor = new ActivityStackSupervisor(this);
2119
2120        mProcessCpuThread = new Thread("CpuTracker") {
2121            @Override
2122            public void run() {
2123                while (true) {
2124                    try {
2125                        try {
2126                            synchronized(this) {
2127                                final long now = SystemClock.uptimeMillis();
2128                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2129                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2130                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2131                                //        + ", write delay=" + nextWriteDelay);
2132                                if (nextWriteDelay < nextCpuDelay) {
2133                                    nextCpuDelay = nextWriteDelay;
2134                                }
2135                                if (nextCpuDelay > 0) {
2136                                    mProcessCpuMutexFree.set(true);
2137                                    this.wait(nextCpuDelay);
2138                                }
2139                            }
2140                        } catch (InterruptedException e) {
2141                        }
2142                        updateCpuStatsNow();
2143                    } catch (Exception e) {
2144                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2145                    }
2146                }
2147            }
2148        };
2149
2150        Watchdog.getInstance().addMonitor(this);
2151        Watchdog.getInstance().addThread(mHandler);
2152    }
2153
2154    public void setSystemServiceManager(SystemServiceManager mgr) {
2155        mSystemServiceManager = mgr;
2156    }
2157
2158    private void start() {
2159        mProcessCpuThread.start();
2160
2161        mBatteryStatsService.publish(mContext);
2162        mUsageStatsService.publish(mContext);
2163        mAppOpsService.publish(mContext);
2164
2165        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2166    }
2167
2168    @Override
2169    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2170            throws RemoteException {
2171        if (code == SYSPROPS_TRANSACTION) {
2172            // We need to tell all apps about the system property change.
2173            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2174            synchronized(this) {
2175                final int NP = mProcessNames.getMap().size();
2176                for (int ip=0; ip<NP; ip++) {
2177                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2178                    final int NA = apps.size();
2179                    for (int ia=0; ia<NA; ia++) {
2180                        ProcessRecord app = apps.valueAt(ia);
2181                        if (app.thread != null) {
2182                            procs.add(app.thread.asBinder());
2183                        }
2184                    }
2185                }
2186            }
2187
2188            int N = procs.size();
2189            for (int i=0; i<N; i++) {
2190                Parcel data2 = Parcel.obtain();
2191                try {
2192                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2193                } catch (RemoteException e) {
2194                }
2195                data2.recycle();
2196            }
2197        }
2198        try {
2199            return super.onTransact(code, data, reply, flags);
2200        } catch (RuntimeException e) {
2201            // The activity manager only throws security exceptions, so let's
2202            // log all others.
2203            if (!(e instanceof SecurityException)) {
2204                Slog.wtf(TAG, "Activity Manager Crash", e);
2205            }
2206            throw e;
2207        }
2208    }
2209
2210    void updateCpuStats() {
2211        final long now = SystemClock.uptimeMillis();
2212        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2213            return;
2214        }
2215        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2216            synchronized (mProcessCpuThread) {
2217                mProcessCpuThread.notify();
2218            }
2219        }
2220    }
2221
2222    void updateCpuStatsNow() {
2223        synchronized (mProcessCpuThread) {
2224            mProcessCpuMutexFree.set(false);
2225            final long now = SystemClock.uptimeMillis();
2226            boolean haveNewCpuStats = false;
2227
2228            if (MONITOR_CPU_USAGE &&
2229                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2230                mLastCpuTime.set(now);
2231                haveNewCpuStats = true;
2232                mProcessCpuTracker.update();
2233                //Slog.i(TAG, mProcessCpu.printCurrentState());
2234                //Slog.i(TAG, "Total CPU usage: "
2235                //        + mProcessCpu.getTotalCpuPercent() + "%");
2236
2237                // Slog the cpu usage if the property is set.
2238                if ("true".equals(SystemProperties.get("events.cpu"))) {
2239                    int user = mProcessCpuTracker.getLastUserTime();
2240                    int system = mProcessCpuTracker.getLastSystemTime();
2241                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2242                    int irq = mProcessCpuTracker.getLastIrqTime();
2243                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2244                    int idle = mProcessCpuTracker.getLastIdleTime();
2245
2246                    int total = user + system + iowait + irq + softIrq + idle;
2247                    if (total == 0) total = 1;
2248
2249                    EventLog.writeEvent(EventLogTags.CPU,
2250                            ((user+system+iowait+irq+softIrq) * 100) / total,
2251                            (user * 100) / total,
2252                            (system * 100) / total,
2253                            (iowait * 100) / total,
2254                            (irq * 100) / total,
2255                            (softIrq * 100) / total);
2256                }
2257            }
2258
2259            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2260            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2261            synchronized(bstats) {
2262                synchronized(mPidsSelfLocked) {
2263                    if (haveNewCpuStats) {
2264                        if (mOnBattery) {
2265                            int perc = bstats.startAddingCpuLocked();
2266                            int totalUTime = 0;
2267                            int totalSTime = 0;
2268                            final int N = mProcessCpuTracker.countStats();
2269                            for (int i=0; i<N; i++) {
2270                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2271                                if (!st.working) {
2272                                    continue;
2273                                }
2274                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2275                                int otherUTime = (st.rel_utime*perc)/100;
2276                                int otherSTime = (st.rel_stime*perc)/100;
2277                                totalUTime += otherUTime;
2278                                totalSTime += otherSTime;
2279                                if (pr != null) {
2280                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2281                                    if (ps == null || !ps.isActive()) {
2282                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2283                                                pr.info.uid, pr.processName);
2284                                    }
2285                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2286                                            st.rel_stime-otherSTime);
2287                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2288                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2289                                } else {
2290                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2291                                    if (ps == null || !ps.isActive()) {
2292                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2293                                                bstats.mapUid(st.uid), st.name);
2294                                    }
2295                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2296                                            st.rel_stime-otherSTime);
2297                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2298                                }
2299                            }
2300                            bstats.finishAddingCpuLocked(perc, totalUTime,
2301                                    totalSTime, cpuSpeedTimes);
2302                        }
2303                    }
2304                }
2305
2306                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2307                    mLastWriteTime = now;
2308                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2309                }
2310            }
2311        }
2312    }
2313
2314    @Override
2315    public void batteryNeedsCpuUpdate() {
2316        updateCpuStatsNow();
2317    }
2318
2319    @Override
2320    public void batteryPowerChanged(boolean onBattery) {
2321        // When plugging in, update the CPU stats first before changing
2322        // the plug state.
2323        updateCpuStatsNow();
2324        synchronized (this) {
2325            synchronized(mPidsSelfLocked) {
2326                mOnBattery = DEBUG_POWER ? true : onBattery;
2327            }
2328        }
2329    }
2330
2331    /**
2332     * Initialize the application bind args. These are passed to each
2333     * process when the bindApplication() IPC is sent to the process. They're
2334     * lazily setup to make sure the services are running when they're asked for.
2335     */
2336    private HashMap<String, IBinder> getCommonServicesLocked() {
2337        if (mAppBindArgs == null) {
2338            mAppBindArgs = new HashMap<String, IBinder>();
2339
2340            // Setup the application init args
2341            mAppBindArgs.put("package", ServiceManager.getService("package"));
2342            mAppBindArgs.put("window", ServiceManager.getService("window"));
2343            mAppBindArgs.put(Context.ALARM_SERVICE,
2344                    ServiceManager.getService(Context.ALARM_SERVICE));
2345        }
2346        return mAppBindArgs;
2347    }
2348
2349    final void setFocusedActivityLocked(ActivityRecord r) {
2350        if (mFocusedActivity != r) {
2351            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2352            mFocusedActivity = r;
2353            if (r.task != null && r.task.voiceInteractor != null) {
2354                startRunningVoiceLocked();
2355            } else {
2356                finishRunningVoiceLocked();
2357            }
2358            mStackSupervisor.setFocusedStack(r);
2359            if (r != null) {
2360                mWindowManager.setFocusedApp(r.appToken, true);
2361            }
2362            applyUpdateLockStateLocked(r);
2363        }
2364    }
2365
2366    final void clearFocusedActivity(ActivityRecord r) {
2367        if (mFocusedActivity == r) {
2368            mFocusedActivity = null;
2369        }
2370    }
2371
2372    @Override
2373    public void setFocusedStack(int stackId) {
2374        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2375        synchronized (ActivityManagerService.this) {
2376            ActivityStack stack = mStackSupervisor.getStack(stackId);
2377            if (stack != null) {
2378                ActivityRecord r = stack.topRunningActivityLocked(null);
2379                if (r != null) {
2380                    setFocusedActivityLocked(r);
2381                }
2382            }
2383        }
2384    }
2385
2386    @Override
2387    public void notifyActivityDrawn(IBinder token) {
2388        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2389        synchronized (this) {
2390            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2391            if (r != null) {
2392                r.task.stack.notifyActivityDrawnLocked(r);
2393            }
2394        }
2395    }
2396
2397    final void applyUpdateLockStateLocked(ActivityRecord r) {
2398        // Modifications to the UpdateLock state are done on our handler, outside
2399        // the activity manager's locks.  The new state is determined based on the
2400        // state *now* of the relevant activity record.  The object is passed to
2401        // the handler solely for logging detail, not to be consulted/modified.
2402        final boolean nextState = r != null && r.immersive;
2403        mHandler.sendMessage(
2404                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2405    }
2406
2407    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2408        Message msg = Message.obtain();
2409        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2410        msg.obj = r.task.askedCompatMode ? null : r;
2411        mHandler.sendMessage(msg);
2412    }
2413
2414    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2415            String what, Object obj, ProcessRecord srcApp) {
2416        app.lastActivityTime = now;
2417
2418        if (app.activities.size() > 0) {
2419            // Don't want to touch dependent processes that are hosting activities.
2420            return index;
2421        }
2422
2423        int lrui = mLruProcesses.lastIndexOf(app);
2424        if (lrui < 0) {
2425            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2426                    + what + " " + obj + " from " + srcApp);
2427            return index;
2428        }
2429
2430        if (lrui >= index) {
2431            // Don't want to cause this to move dependent processes *back* in the
2432            // list as if they were less frequently used.
2433            return index;
2434        }
2435
2436        if (lrui >= mLruProcessActivityStart) {
2437            // Don't want to touch dependent processes that are hosting activities.
2438            return index;
2439        }
2440
2441        mLruProcesses.remove(lrui);
2442        if (index > 0) {
2443            index--;
2444        }
2445        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2446                + " in LRU list: " + app);
2447        mLruProcesses.add(index, app);
2448        return index;
2449    }
2450
2451    final void removeLruProcessLocked(ProcessRecord app) {
2452        int lrui = mLruProcesses.lastIndexOf(app);
2453        if (lrui >= 0) {
2454            if (lrui <= mLruProcessActivityStart) {
2455                mLruProcessActivityStart--;
2456            }
2457            if (lrui <= mLruProcessServiceStart) {
2458                mLruProcessServiceStart--;
2459            }
2460            mLruProcesses.remove(lrui);
2461        }
2462    }
2463
2464    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2465            ProcessRecord client) {
2466        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2467                || app.treatLikeActivity;
2468        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2469        if (!activityChange && hasActivity) {
2470            // The process has activities, so we are only allowing activity-based adjustments
2471            // to move it.  It should be kept in the front of the list with other
2472            // processes that have activities, and we don't want those to change their
2473            // order except due to activity operations.
2474            return;
2475        }
2476
2477        mLruSeq++;
2478        final long now = SystemClock.uptimeMillis();
2479        app.lastActivityTime = now;
2480
2481        // First a quick reject: if the app is already at the position we will
2482        // put it, then there is nothing to do.
2483        if (hasActivity) {
2484            final int N = mLruProcesses.size();
2485            if (N > 0 && mLruProcesses.get(N-1) == app) {
2486                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2487                return;
2488            }
2489        } else {
2490            if (mLruProcessServiceStart > 0
2491                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2492                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2493                return;
2494            }
2495        }
2496
2497        int lrui = mLruProcesses.lastIndexOf(app);
2498
2499        if (app.persistent && lrui >= 0) {
2500            // We don't care about the position of persistent processes, as long as
2501            // they are in the list.
2502            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2503            return;
2504        }
2505
2506        /* In progress: compute new position first, so we can avoid doing work
2507           if the process is not actually going to move.  Not yet working.
2508        int addIndex;
2509        int nextIndex;
2510        boolean inActivity = false, inService = false;
2511        if (hasActivity) {
2512            // Process has activities, put it at the very tipsy-top.
2513            addIndex = mLruProcesses.size();
2514            nextIndex = mLruProcessServiceStart;
2515            inActivity = true;
2516        } else if (hasService) {
2517            // Process has services, put it at the top of the service list.
2518            addIndex = mLruProcessActivityStart;
2519            nextIndex = mLruProcessServiceStart;
2520            inActivity = true;
2521            inService = true;
2522        } else  {
2523            // Process not otherwise of interest, it goes to the top of the non-service area.
2524            addIndex = mLruProcessServiceStart;
2525            if (client != null) {
2526                int clientIndex = mLruProcesses.lastIndexOf(client);
2527                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2528                        + app);
2529                if (clientIndex >= 0 && addIndex > clientIndex) {
2530                    addIndex = clientIndex;
2531                }
2532            }
2533            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2534        }
2535
2536        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2537                + mLruProcessActivityStart + "): " + app);
2538        */
2539
2540        if (lrui >= 0) {
2541            if (lrui < mLruProcessActivityStart) {
2542                mLruProcessActivityStart--;
2543            }
2544            if (lrui < mLruProcessServiceStart) {
2545                mLruProcessServiceStart--;
2546            }
2547            /*
2548            if (addIndex > lrui) {
2549                addIndex--;
2550            }
2551            if (nextIndex > lrui) {
2552                nextIndex--;
2553            }
2554            */
2555            mLruProcesses.remove(lrui);
2556        }
2557
2558        /*
2559        mLruProcesses.add(addIndex, app);
2560        if (inActivity) {
2561            mLruProcessActivityStart++;
2562        }
2563        if (inService) {
2564            mLruProcessActivityStart++;
2565        }
2566        */
2567
2568        int nextIndex;
2569        if (hasActivity) {
2570            final int N = mLruProcesses.size();
2571            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2572                // Process doesn't have activities, but has clients with
2573                // activities...  move it up, but one below the top (the top
2574                // should always have a real activity).
2575                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2576                mLruProcesses.add(N-1, app);
2577                // To keep it from spamming the LRU list (by making a bunch of clients),
2578                // we will push down any other entries owned by the app.
2579                final int uid = app.info.uid;
2580                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2581                    ProcessRecord subProc = mLruProcesses.get(i);
2582                    if (subProc.info.uid == uid) {
2583                        // We want to push this one down the list.  If the process after
2584                        // it is for the same uid, however, don't do so, because we don't
2585                        // want them internally to be re-ordered.
2586                        if (mLruProcesses.get(i-1).info.uid != uid) {
2587                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2588                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2589                            ProcessRecord tmp = mLruProcesses.get(i);
2590                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2591                            mLruProcesses.set(i-1, tmp);
2592                            i--;
2593                        }
2594                    } else {
2595                        // A gap, we can stop here.
2596                        break;
2597                    }
2598                }
2599            } else {
2600                // Process has activities, put it at the very tipsy-top.
2601                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2602                mLruProcesses.add(app);
2603            }
2604            nextIndex = mLruProcessServiceStart;
2605        } else if (hasService) {
2606            // Process has services, put it at the top of the service list.
2607            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2608            mLruProcesses.add(mLruProcessActivityStart, app);
2609            nextIndex = mLruProcessServiceStart;
2610            mLruProcessActivityStart++;
2611        } else  {
2612            // Process not otherwise of interest, it goes to the top of the non-service area.
2613            int index = mLruProcessServiceStart;
2614            if (client != null) {
2615                // If there is a client, don't allow the process to be moved up higher
2616                // in the list than that client.
2617                int clientIndex = mLruProcesses.lastIndexOf(client);
2618                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2619                        + " when updating " + app);
2620                if (clientIndex <= lrui) {
2621                    // Don't allow the client index restriction to push it down farther in the
2622                    // list than it already is.
2623                    clientIndex = lrui;
2624                }
2625                if (clientIndex >= 0 && index > clientIndex) {
2626                    index = clientIndex;
2627                }
2628            }
2629            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2630            mLruProcesses.add(index, app);
2631            nextIndex = index-1;
2632            mLruProcessActivityStart++;
2633            mLruProcessServiceStart++;
2634        }
2635
2636        // If the app is currently using a content provider or service,
2637        // bump those processes as well.
2638        for (int j=app.connections.size()-1; j>=0; j--) {
2639            ConnectionRecord cr = app.connections.valueAt(j);
2640            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2641                    && cr.binding.service.app != null
2642                    && cr.binding.service.app.lruSeq != mLruSeq
2643                    && !cr.binding.service.app.persistent) {
2644                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2645                        "service connection", cr, app);
2646            }
2647        }
2648        for (int j=app.conProviders.size()-1; j>=0; j--) {
2649            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2650            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2651                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2652                        "provider reference", cpr, app);
2653            }
2654        }
2655    }
2656
2657    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2658        if (uid == Process.SYSTEM_UID) {
2659            // The system gets to run in any process.  If there are multiple
2660            // processes with the same uid, just pick the first (this
2661            // should never happen).
2662            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2663            if (procs == null) return null;
2664            final int N = procs.size();
2665            for (int i = 0; i < N; i++) {
2666                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2667            }
2668        }
2669        ProcessRecord proc = mProcessNames.get(processName, uid);
2670        if (false && proc != null && !keepIfLarge
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2672                && proc.lastCachedPss >= 4000) {
2673            // Turn this condition on to cause killing to happen regularly, for testing.
2674            if (proc.baseProcessTracker != null) {
2675                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676            }
2677            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2678                    + "k from cached");
2679        } else if (proc != null && !keepIfLarge
2680                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2681                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2682            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2683            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2684                if (proc.baseProcessTracker != null) {
2685                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2686                }
2687                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2688                        + "k from cached");
2689            }
2690        }
2691        return proc;
2692    }
2693
2694    void ensurePackageDexOpt(String packageName) {
2695        IPackageManager pm = AppGlobals.getPackageManager();
2696        try {
2697            if (pm.performDexOpt(packageName)) {
2698                mDidDexOpt = true;
2699            }
2700        } catch (RemoteException e) {
2701        }
2702    }
2703
2704    boolean isNextTransitionForward() {
2705        int transit = mWindowManager.getPendingAppTransition();
2706        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2707                || transit == AppTransition.TRANSIT_TASK_OPEN
2708                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2709    }
2710
2711    final ProcessRecord startProcessLocked(String processName,
2712            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2713            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2714            boolean isolated, boolean keepIfLarge) {
2715        ProcessRecord app;
2716        if (!isolated) {
2717            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2718        } else {
2719            // If this is an isolated process, it can't re-use an existing process.
2720            app = null;
2721        }
2722        // We don't have to do anything more if:
2723        // (1) There is an existing application record; and
2724        // (2) The caller doesn't think it is dead, OR there is no thread
2725        //     object attached to it so we know it couldn't have crashed; and
2726        // (3) There is a pid assigned to it, so it is either starting or
2727        //     already running.
2728        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2729                + " app=" + app + " knownToBeDead=" + knownToBeDead
2730                + " thread=" + (app != null ? app.thread : null)
2731                + " pid=" + (app != null ? app.pid : -1));
2732        if (app != null && app.pid > 0) {
2733            if (!knownToBeDead || app.thread == null) {
2734                // We already have the app running, or are waiting for it to
2735                // come up (we have a pid but not yet its thread), so keep it.
2736                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2737                // If this is a new package in the process, add the package to the list
2738                app.addPackage(info.packageName, mProcessStats);
2739                return app;
2740            }
2741
2742            // An application record is attached to a previous process,
2743            // clean it up now.
2744            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2745            handleAppDiedLocked(app, true, true);
2746        }
2747
2748        String hostingNameStr = hostingName != null
2749                ? hostingName.flattenToShortString() : null;
2750
2751        if (!isolated) {
2752            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2753                // If we are in the background, then check to see if this process
2754                // is bad.  If so, we will just silently fail.
2755                if (mBadProcesses.get(info.processName, info.uid) != null) {
2756                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2757                            + "/" + info.processName);
2758                    return null;
2759                }
2760            } else {
2761                // When the user is explicitly starting a process, then clear its
2762                // crash count so that we won't make it bad until they see at
2763                // least one crash dialog again, and make the process good again
2764                // if it had been bad.
2765                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2766                        + "/" + info.processName);
2767                mProcessCrashTimes.remove(info.processName, info.uid);
2768                if (mBadProcesses.get(info.processName, info.uid) != null) {
2769                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2770                            UserHandle.getUserId(info.uid), info.uid,
2771                            info.processName);
2772                    mBadProcesses.remove(info.processName, info.uid);
2773                    if (app != null) {
2774                        app.bad = false;
2775                    }
2776                }
2777            }
2778        }
2779
2780        if (app == null) {
2781            app = newProcessRecordLocked(info, processName, isolated);
2782            if (app == null) {
2783                Slog.w(TAG, "Failed making new process record for "
2784                        + processName + "/" + info.uid + " isolated=" + isolated);
2785                return null;
2786            }
2787            mProcessNames.put(processName, app.uid, app);
2788            if (isolated) {
2789                mIsolatedProcesses.put(app.uid, app);
2790            }
2791        } else {
2792            // If this is a new package in the process, add the package to the list
2793            app.addPackage(info.packageName, mProcessStats);
2794        }
2795
2796        // If the system is not ready yet, then hold off on starting this
2797        // process until it is.
2798        if (!mProcessesReady
2799                && !isAllowedWhileBooting(info)
2800                && !allowWhileBooting) {
2801            if (!mProcessesOnHold.contains(app)) {
2802                mProcessesOnHold.add(app);
2803            }
2804            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2805            return app;
2806        }
2807
2808        startProcessLocked(app, hostingType, hostingNameStr);
2809        return (app.pid != 0) ? app : null;
2810    }
2811
2812    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2813        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2814    }
2815
2816    private final void startProcessLocked(ProcessRecord app,
2817            String hostingType, String hostingNameStr) {
2818        if (app.pid > 0 && app.pid != MY_PID) {
2819            synchronized (mPidsSelfLocked) {
2820                mPidsSelfLocked.remove(app.pid);
2821                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2822            }
2823            app.setPid(0);
2824        }
2825
2826        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2827                "startProcessLocked removing on hold: " + app);
2828        mProcessesOnHold.remove(app);
2829
2830        updateCpuStats();
2831
2832        try {
2833            int uid = app.uid;
2834
2835            int[] gids = null;
2836            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2837            if (!app.isolated) {
2838                int[] permGids = null;
2839                try {
2840                    final PackageManager pm = mContext.getPackageManager();
2841                    permGids = pm.getPackageGids(app.info.packageName);
2842
2843                    if (Environment.isExternalStorageEmulated()) {
2844                        if (pm.checkPermission(
2845                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2846                                app.info.packageName) == PERMISSION_GRANTED) {
2847                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2848                        } else {
2849                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2850                        }
2851                    }
2852                } catch (PackageManager.NameNotFoundException e) {
2853                    Slog.w(TAG, "Unable to retrieve gids", e);
2854                }
2855
2856                /*
2857                 * Add shared application GID so applications can share some
2858                 * resources like shared libraries
2859                 */
2860                if (permGids == null) {
2861                    gids = new int[1];
2862                } else {
2863                    gids = new int[permGids.length + 1];
2864                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2865                }
2866                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2867            }
2868            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2869                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2870                        && mTopComponent != null
2871                        && app.processName.equals(mTopComponent.getPackageName())) {
2872                    uid = 0;
2873                }
2874                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2875                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2876                    uid = 0;
2877                }
2878            }
2879            int debugFlags = 0;
2880            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2881                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2882                // Also turn on CheckJNI for debuggable apps. It's quite
2883                // awkward to turn on otherwise.
2884                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2885            }
2886            // Run the app in safe mode if its manifest requests so or the
2887            // system is booted in safe mode.
2888            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2889                mSafeMode == true) {
2890                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2891            }
2892            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2893                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2894            }
2895            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2896                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2897            }
2898            if ("1".equals(SystemProperties.get("debug.assert"))) {
2899                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2900            }
2901
2902            String requiredAbi = app.info.requiredCpuAbi;
2903            if (requiredAbi == null) {
2904                requiredAbi = Build.SUPPORTED_ABIS[0];
2905            }
2906
2907            // Start the process.  It will either succeed and return a result containing
2908            // the PID of the new process, or else throw a RuntimeException.
2909            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2910                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2911                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2912
2913            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2914            synchronized (bs) {
2915                if (bs.isOnBattery()) {
2916                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2917                }
2918            }
2919
2920            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2921                    UserHandle.getUserId(uid), startResult.pid, uid,
2922                    app.processName, hostingType,
2923                    hostingNameStr != null ? hostingNameStr : "");
2924
2925            if (app.persistent) {
2926                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2927            }
2928
2929            StringBuilder buf = mStringBuilder;
2930            buf.setLength(0);
2931            buf.append("Start proc ");
2932            buf.append(app.processName);
2933            buf.append(" for ");
2934            buf.append(hostingType);
2935            if (hostingNameStr != null) {
2936                buf.append(" ");
2937                buf.append(hostingNameStr);
2938            }
2939            buf.append(": pid=");
2940            buf.append(startResult.pid);
2941            buf.append(" uid=");
2942            buf.append(uid);
2943            buf.append(" gids={");
2944            if (gids != null) {
2945                for (int gi=0; gi<gids.length; gi++) {
2946                    if (gi != 0) buf.append(", ");
2947                    buf.append(gids[gi]);
2948
2949                }
2950            }
2951            buf.append("}");
2952            Slog.i(TAG, buf.toString());
2953            app.setPid(startResult.pid);
2954            app.usingWrapper = startResult.usingWrapper;
2955            app.removed = false;
2956            synchronized (mPidsSelfLocked) {
2957                this.mPidsSelfLocked.put(startResult.pid, app);
2958                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2959                msg.obj = app;
2960                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2961                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2962            }
2963            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2964                    app.processName, app.info.uid);
2965            if (app.isolated) {
2966                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2967            }
2968        } catch (RuntimeException e) {
2969            // XXX do better error recovery.
2970            app.setPid(0);
2971            Slog.e(TAG, "Failure starting process " + app.processName, e);
2972        }
2973    }
2974
2975    void updateUsageStats(ActivityRecord component, boolean resumed) {
2976        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2977        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2978        if (resumed) {
2979            mUsageStatsService.noteResumeComponent(component.realActivity);
2980            synchronized (stats) {
2981                stats.noteActivityResumedLocked(component.app.uid);
2982            }
2983        } else {
2984            mUsageStatsService.notePauseComponent(component.realActivity);
2985            synchronized (stats) {
2986                stats.noteActivityPausedLocked(component.app.uid);
2987            }
2988        }
2989    }
2990
2991    Intent getHomeIntent() {
2992        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2993        intent.setComponent(mTopComponent);
2994        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2995            intent.addCategory(Intent.CATEGORY_HOME);
2996        }
2997        return intent;
2998    }
2999
3000    boolean startHomeActivityLocked(int userId) {
3001        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3002                && mTopAction == null) {
3003            // We are running in factory test mode, but unable to find
3004            // the factory test app, so just sit around displaying the
3005            // error message and don't try to start anything.
3006            return false;
3007        }
3008        Intent intent = getHomeIntent();
3009        ActivityInfo aInfo =
3010            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3011        if (aInfo != null) {
3012            intent.setComponent(new ComponentName(
3013                    aInfo.applicationInfo.packageName, aInfo.name));
3014            // Don't do this if the home app is currently being
3015            // instrumented.
3016            aInfo = new ActivityInfo(aInfo);
3017            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3018            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3019                    aInfo.applicationInfo.uid, true);
3020            if (app == null || app.instrumentationClass == null) {
3021                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3022                mStackSupervisor.startHomeActivity(intent, aInfo);
3023            }
3024        }
3025
3026        return true;
3027    }
3028
3029    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3030        ActivityInfo ai = null;
3031        ComponentName comp = intent.getComponent();
3032        try {
3033            if (comp != null) {
3034                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3035            } else {
3036                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3037                        intent,
3038                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3039                            flags, userId);
3040
3041                if (info != null) {
3042                    ai = info.activityInfo;
3043                }
3044            }
3045        } catch (RemoteException e) {
3046            // ignore
3047        }
3048
3049        return ai;
3050    }
3051
3052    /**
3053     * Starts the "new version setup screen" if appropriate.
3054     */
3055    void startSetupActivityLocked() {
3056        // Only do this once per boot.
3057        if (mCheckedForSetup) {
3058            return;
3059        }
3060
3061        // We will show this screen if the current one is a different
3062        // version than the last one shown, and we are not running in
3063        // low-level factory test mode.
3064        final ContentResolver resolver = mContext.getContentResolver();
3065        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3066                Settings.Global.getInt(resolver,
3067                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3068            mCheckedForSetup = true;
3069
3070            // See if we should be showing the platform update setup UI.
3071            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3072            List<ResolveInfo> ris = mContext.getPackageManager()
3073                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3074
3075            // We don't allow third party apps to replace this.
3076            ResolveInfo ri = null;
3077            for (int i=0; ris != null && i<ris.size(); i++) {
3078                if ((ris.get(i).activityInfo.applicationInfo.flags
3079                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3080                    ri = ris.get(i);
3081                    break;
3082                }
3083            }
3084
3085            if (ri != null) {
3086                String vers = ri.activityInfo.metaData != null
3087                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3088                        : null;
3089                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3090                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3091                            Intent.METADATA_SETUP_VERSION);
3092                }
3093                String lastVers = Settings.Secure.getString(
3094                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3095                if (vers != null && !vers.equals(lastVers)) {
3096                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3097                    intent.setComponent(new ComponentName(
3098                            ri.activityInfo.packageName, ri.activityInfo.name));
3099                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3100                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3101                }
3102            }
3103        }
3104    }
3105
3106    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3107        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3108    }
3109
3110    void enforceNotIsolatedCaller(String caller) {
3111        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3112            throw new SecurityException("Isolated process not allowed to call " + caller);
3113        }
3114    }
3115
3116    @Override
3117    public int getFrontActivityScreenCompatMode() {
3118        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3119        synchronized (this) {
3120            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3121        }
3122    }
3123
3124    @Override
3125    public void setFrontActivityScreenCompatMode(int mode) {
3126        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3127                "setFrontActivityScreenCompatMode");
3128        synchronized (this) {
3129            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3130        }
3131    }
3132
3133    @Override
3134    public int getPackageScreenCompatMode(String packageName) {
3135        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3136        synchronized (this) {
3137            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3138        }
3139    }
3140
3141    @Override
3142    public void setPackageScreenCompatMode(String packageName, int mode) {
3143        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3144                "setPackageScreenCompatMode");
3145        synchronized (this) {
3146            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3147        }
3148    }
3149
3150    @Override
3151    public boolean getPackageAskScreenCompat(String packageName) {
3152        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3153        synchronized (this) {
3154            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3155        }
3156    }
3157
3158    @Override
3159    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3160        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3161                "setPackageAskScreenCompat");
3162        synchronized (this) {
3163            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3164        }
3165    }
3166
3167    private void dispatchProcessesChanged() {
3168        int N;
3169        synchronized (this) {
3170            N = mPendingProcessChanges.size();
3171            if (mActiveProcessChanges.length < N) {
3172                mActiveProcessChanges = new ProcessChangeItem[N];
3173            }
3174            mPendingProcessChanges.toArray(mActiveProcessChanges);
3175            mAvailProcessChanges.addAll(mPendingProcessChanges);
3176            mPendingProcessChanges.clear();
3177            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3178        }
3179
3180        int i = mProcessObservers.beginBroadcast();
3181        while (i > 0) {
3182            i--;
3183            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3184            if (observer != null) {
3185                try {
3186                    for (int j=0; j<N; j++) {
3187                        ProcessChangeItem item = mActiveProcessChanges[j];
3188                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3189                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3190                                    + item.pid + " uid=" + item.uid + ": "
3191                                    + item.foregroundActivities);
3192                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3193                                    item.foregroundActivities);
3194                        }
3195                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3196                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3197                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3198                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3199                        }
3200                    }
3201                } catch (RemoteException e) {
3202                }
3203            }
3204        }
3205        mProcessObservers.finishBroadcast();
3206    }
3207
3208    private void dispatchProcessDied(int pid, int uid) {
3209        int i = mProcessObservers.beginBroadcast();
3210        while (i > 0) {
3211            i--;
3212            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3213            if (observer != null) {
3214                try {
3215                    observer.onProcessDied(pid, uid);
3216                } catch (RemoteException e) {
3217                }
3218            }
3219        }
3220        mProcessObservers.finishBroadcast();
3221    }
3222
3223    final void doPendingActivityLaunchesLocked(boolean doResume) {
3224        final int N = mPendingActivityLaunches.size();
3225        if (N <= 0) {
3226            return;
3227        }
3228        for (int i=0; i<N; i++) {
3229            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3230            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3231                    doResume && i == (N-1), null);
3232        }
3233        mPendingActivityLaunches.clear();
3234    }
3235
3236    @Override
3237    public final int startActivity(IApplicationThread caller, String callingPackage,
3238            Intent intent, String resolvedType, IBinder resultTo,
3239            String resultWho, int requestCode, int startFlags,
3240            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3241        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3242                resultWho, requestCode,
3243                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3244    }
3245
3246    @Override
3247    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3248            Intent intent, String resolvedType, IBinder resultTo,
3249            String resultWho, int requestCode, int startFlags,
3250            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3251        enforceNotIsolatedCaller("startActivity");
3252        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3253                false, true, "startActivity", null);
3254        // TODO: Switch to user app stacks here.
3255        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3256                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3257                null, null, options, userId, null);
3258    }
3259
3260    @Override
3261    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3262            Intent intent, String resolvedType, IBinder resultTo,
3263            String resultWho, int requestCode, int startFlags, String profileFile,
3264            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3265        enforceNotIsolatedCaller("startActivityAndWait");
3266        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3267                false, true, "startActivityAndWait", null);
3268        WaitResult res = new WaitResult();
3269        // TODO: Switch to user app stacks here.
3270        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3271                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3272                res, null, options, UserHandle.getCallingUserId(), null);
3273        return res;
3274    }
3275
3276    @Override
3277    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3278            Intent intent, String resolvedType, IBinder resultTo,
3279            String resultWho, int requestCode, int startFlags, Configuration config,
3280            Bundle options, int userId) {
3281        enforceNotIsolatedCaller("startActivityWithConfig");
3282        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3283                false, true, "startActivityWithConfig", null);
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3286                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, config, options, userId, null);
3288        return ret;
3289    }
3290
3291    @Override
3292    public int startActivityIntentSender(IApplicationThread caller,
3293            IntentSender intent, Intent fillInIntent, String resolvedType,
3294            IBinder resultTo, String resultWho, int requestCode,
3295            int flagsMask, int flagsValues, Bundle options) {
3296        enforceNotIsolatedCaller("startActivityIntentSender");
3297        // Refuse possible leaked file descriptors
3298        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3299            throw new IllegalArgumentException("File descriptors passed in Intent");
3300        }
3301
3302        IIntentSender sender = intent.getTarget();
3303        if (!(sender instanceof PendingIntentRecord)) {
3304            throw new IllegalArgumentException("Bad PendingIntent object");
3305        }
3306
3307        PendingIntentRecord pir = (PendingIntentRecord)sender;
3308
3309        synchronized (this) {
3310            // If this is coming from the currently resumed activity, it is
3311            // effectively saying that app switches are allowed at this point.
3312            final ActivityStack stack = getFocusedStack();
3313            if (stack.mResumedActivity != null &&
3314                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3315                mAppSwitchesAllowedTime = 0;
3316            }
3317        }
3318        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3319                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3320        return ret;
3321    }
3322
3323    @Override
3324    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3325            Intent intent, String resolvedType, IVoiceInteractionSession session,
3326            IVoiceInteractor interactor, int startFlags, String profileFile,
3327            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3328        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3329                != PackageManager.PERMISSION_GRANTED) {
3330            String msg = "Permission Denial: startVoiceActivity() from pid="
3331                    + Binder.getCallingPid()
3332                    + ", uid=" + Binder.getCallingUid()
3333                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3334            Slog.w(TAG, msg);
3335            throw new SecurityException(msg);
3336        }
3337        if (session == null || interactor == null) {
3338            throw new NullPointerException("null session or interactor");
3339        }
3340        userId = handleIncomingUser(callingPid, callingUid, userId,
3341                false, true, "startVoiceActivity", null);
3342        // TODO: Switch to user app stacks here.
3343        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3344                resolvedType, session, interactor, null, null, 0, startFlags,
3345                profileFile, profileFd, null, null, options, userId, null);
3346    }
3347
3348    @Override
3349    public boolean startNextMatchingActivity(IBinder callingActivity,
3350            Intent intent, Bundle options) {
3351        // Refuse possible leaked file descriptors
3352        if (intent != null && intent.hasFileDescriptors() == true) {
3353            throw new IllegalArgumentException("File descriptors passed in Intent");
3354        }
3355
3356        synchronized (this) {
3357            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3358            if (r == null) {
3359                ActivityOptions.abort(options);
3360                return false;
3361            }
3362            if (r.app == null || r.app.thread == null) {
3363                // The caller is not running...  d'oh!
3364                ActivityOptions.abort(options);
3365                return false;
3366            }
3367            intent = new Intent(intent);
3368            // The caller is not allowed to change the data.
3369            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3370            // And we are resetting to find the next component...
3371            intent.setComponent(null);
3372
3373            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3374
3375            ActivityInfo aInfo = null;
3376            try {
3377                List<ResolveInfo> resolves =
3378                    AppGlobals.getPackageManager().queryIntentActivities(
3379                            intent, r.resolvedType,
3380                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3381                            UserHandle.getCallingUserId());
3382
3383                // Look for the original activity in the list...
3384                final int N = resolves != null ? resolves.size() : 0;
3385                for (int i=0; i<N; i++) {
3386                    ResolveInfo rInfo = resolves.get(i);
3387                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3388                            && rInfo.activityInfo.name.equals(r.info.name)) {
3389                        // We found the current one...  the next matching is
3390                        // after it.
3391                        i++;
3392                        if (i<N) {
3393                            aInfo = resolves.get(i).activityInfo;
3394                        }
3395                        if (debug) {
3396                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3397                                    + "/" + r.info.name);
3398                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3399                                    + "/" + aInfo.name);
3400                        }
3401                        break;
3402                    }
3403                }
3404            } catch (RemoteException e) {
3405            }
3406
3407            if (aInfo == null) {
3408                // Nobody who is next!
3409                ActivityOptions.abort(options);
3410                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3411                return false;
3412            }
3413
3414            intent.setComponent(new ComponentName(
3415                    aInfo.applicationInfo.packageName, aInfo.name));
3416            intent.setFlags(intent.getFlags()&~(
3417                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3418                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3419                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3420                    Intent.FLAG_ACTIVITY_NEW_TASK));
3421
3422            // Okay now we need to start the new activity, replacing the
3423            // currently running activity.  This is a little tricky because
3424            // we want to start the new one as if the current one is finished,
3425            // but not finish the current one first so that there is no flicker.
3426            // And thus...
3427            final boolean wasFinishing = r.finishing;
3428            r.finishing = true;
3429
3430            // Propagate reply information over to the new activity.
3431            final ActivityRecord resultTo = r.resultTo;
3432            final String resultWho = r.resultWho;
3433            final int requestCode = r.requestCode;
3434            r.resultTo = null;
3435            if (resultTo != null) {
3436                resultTo.removeResultsLocked(r, resultWho, requestCode);
3437            }
3438
3439            final long origId = Binder.clearCallingIdentity();
3440            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3441                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3442                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3443                    options, false, null, null);
3444            Binder.restoreCallingIdentity(origId);
3445
3446            r.finishing = wasFinishing;
3447            if (res != ActivityManager.START_SUCCESS) {
3448                return false;
3449            }
3450            return true;
3451        }
3452    }
3453
3454    final int startActivityInPackage(int uid, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo,
3456            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3457                    IActivityContainer container) {
3458
3459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3460                false, true, "startActivityInPackage", null);
3461
3462        // TODO: Switch to user app stacks here.
3463        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3464                null, null, resultTo, resultWho, requestCode, startFlags,
3465                null, null, null, null, options, userId, container);
3466        return ret;
3467    }
3468
3469    @Override
3470    public final int startActivities(IApplicationThread caller, String callingPackage,
3471            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3472            int userId) {
3473        enforceNotIsolatedCaller("startActivities");
3474        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3475                false, true, "startActivity", null);
3476        // TODO: Switch to user app stacks here.
3477        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3478                resolvedTypes, resultTo, options, userId);
3479        return ret;
3480    }
3481
3482    final int startActivitiesInPackage(int uid, String callingPackage,
3483            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3484            Bundle options, int userId) {
3485
3486        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3487                false, true, "startActivityInPackage", null);
3488        // TODO: Switch to user app stacks here.
3489        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3490                resultTo, options, userId);
3491        return ret;
3492    }
3493
3494    final void addRecentTaskLocked(TaskRecord task) {
3495        int N = mRecentTasks.size();
3496        // Quick case: check if the top-most recent task is the same.
3497        if (N > 0 && mRecentTasks.get(0) == task) {
3498            return;
3499        }
3500        // Another quick case: never add voice sessions.
3501        if (task.voiceSession != null) {
3502            return;
3503        }
3504        // Remove any existing entries that are the same kind of task.
3505        final Intent intent = task.intent;
3506        final boolean document = intent != null && intent.isDocument();
3507        for (int i=0; i<N; i++) {
3508            TaskRecord tr = mRecentTasks.get(i);
3509            if (task != tr) {
3510                if (task.userId != tr.userId) {
3511                    continue;
3512                }
3513                final Intent trIntent = tr.intent;
3514                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3515                    (intent == null || !intent.filterEquals(trIntent))) {
3516                    continue;
3517                }
3518                if (document || trIntent != null && trIntent.isDocument()) {
3519                    // Document tasks do not match other tasks.
3520                    continue;
3521                }
3522            }
3523
3524            // Either task and tr are the same or, their affinities match or their intents match
3525            // and neither of them is a document.
3526            tr.disposeThumbnail();
3527            mRecentTasks.remove(i);
3528            i--;
3529            N--;
3530            if (task.intent == null) {
3531                // If the new recent task we are adding is not fully
3532                // specified, then replace it with the existing recent task.
3533                task = tr;
3534            }
3535        }
3536        if (N >= MAX_RECENT_TASKS) {
3537            mRecentTasks.remove(N-1).disposeThumbnail();
3538        }
3539        mRecentTasks.add(0, task);
3540    }
3541
3542    @Override
3543    public void reportActivityFullyDrawn(IBinder token) {
3544        synchronized (this) {
3545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3546            if (r == null) {
3547                return;
3548            }
3549            r.reportFullyDrawnLocked();
3550        }
3551    }
3552
3553    @Override
3554    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3555        synchronized (this) {
3556            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3557            if (r == null) {
3558                return;
3559            }
3560            final long origId = Binder.clearCallingIdentity();
3561            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3562            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3563                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3564            if (config != null) {
3565                r.frozenBeforeDestroy = true;
3566                if (!updateConfigurationLocked(config, r, false, false)) {
3567                    mStackSupervisor.resumeTopActivitiesLocked();
3568                }
3569            }
3570            Binder.restoreCallingIdentity(origId);
3571        }
3572    }
3573
3574    @Override
3575    public int getRequestedOrientation(IBinder token) {
3576        synchronized (this) {
3577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3578            if (r == null) {
3579                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3580            }
3581            return mWindowManager.getAppOrientation(r.appToken);
3582        }
3583    }
3584
3585    /**
3586     * This is the internal entry point for handling Activity.finish().
3587     *
3588     * @param token The Binder token referencing the Activity we want to finish.
3589     * @param resultCode Result code, if any, from this Activity.
3590     * @param resultData Result data (Intent), if any, from this Activity.
3591     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3592     *            the root Activity in the task.
3593     *
3594     * @return Returns true if the activity successfully finished, or false if it is still running.
3595     */
3596    @Override
3597    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3598            boolean finishTask) {
3599        // Refuse possible leaked file descriptors
3600        if (resultData != null && resultData.hasFileDescriptors() == true) {
3601            throw new IllegalArgumentException("File descriptors passed in Intent");
3602        }
3603
3604        synchronized(this) {
3605            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3606            if (r == null) {
3607                return true;
3608            }
3609            // Keep track of the root activity of the task before we finish it
3610            TaskRecord tr = r.task;
3611            ActivityRecord rootR = tr.getRootActivity();
3612            if (mController != null) {
3613                // Find the first activity that is not finishing.
3614                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3615                if (next != null) {
3616                    // ask watcher if this is allowed
3617                    boolean resumeOK = true;
3618                    try {
3619                        resumeOK = mController.activityResuming(next.packageName);
3620                    } catch (RemoteException e) {
3621                        mController = null;
3622                        Watchdog.getInstance().setActivityController(null);
3623                    }
3624
3625                    if (!resumeOK) {
3626                        return false;
3627                    }
3628                }
3629            }
3630            final long origId = Binder.clearCallingIdentity();
3631            try {
3632                boolean res;
3633                if (finishTask && r == rootR) {
3634                    // If requested, remove the task that is associated to this activity only if it
3635                    // was the root activity in the task.  The result code and data is ignored because
3636                    // we don't support returning them across task boundaries.
3637                    res = removeTaskByIdLocked(tr.taskId, 0);
3638                } else {
3639                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3640                            resultData, "app-request", true);
3641                }
3642                return res;
3643            } finally {
3644                Binder.restoreCallingIdentity(origId);
3645            }
3646        }
3647    }
3648
3649    @Override
3650    public final void finishHeavyWeightApp() {
3651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3652                != PackageManager.PERMISSION_GRANTED) {
3653            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3654                    + Binder.getCallingPid()
3655                    + ", uid=" + Binder.getCallingUid()
3656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3657            Slog.w(TAG, msg);
3658            throw new SecurityException(msg);
3659        }
3660
3661        synchronized(this) {
3662            if (mHeavyWeightProcess == null) {
3663                return;
3664            }
3665
3666            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3667                    mHeavyWeightProcess.activities);
3668            for (int i=0; i<activities.size(); i++) {
3669                ActivityRecord r = activities.get(i);
3670                if (!r.finishing) {
3671                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3672                            null, "finish-heavy", true);
3673                }
3674            }
3675
3676            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3677                    mHeavyWeightProcess.userId, 0));
3678            mHeavyWeightProcess = null;
3679        }
3680    }
3681
3682    @Override
3683    public void crashApplication(int uid, int initialPid, String packageName,
3684            String message) {
3685        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3686                != PackageManager.PERMISSION_GRANTED) {
3687            String msg = "Permission Denial: crashApplication() from pid="
3688                    + Binder.getCallingPid()
3689                    + ", uid=" + Binder.getCallingUid()
3690                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3691            Slog.w(TAG, msg);
3692            throw new SecurityException(msg);
3693        }
3694
3695        synchronized(this) {
3696            ProcessRecord proc = null;
3697
3698            // Figure out which process to kill.  We don't trust that initialPid
3699            // still has any relation to current pids, so must scan through the
3700            // list.
3701            synchronized (mPidsSelfLocked) {
3702                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3703                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3704                    if (p.uid != uid) {
3705                        continue;
3706                    }
3707                    if (p.pid == initialPid) {
3708                        proc = p;
3709                        break;
3710                    }
3711                    if (p.pkgList.containsKey(packageName)) {
3712                        proc = p;
3713                    }
3714                }
3715            }
3716
3717            if (proc == null) {
3718                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3719                        + " initialPid=" + initialPid
3720                        + " packageName=" + packageName);
3721                return;
3722            }
3723
3724            if (proc.thread != null) {
3725                if (proc.pid == Process.myPid()) {
3726                    Log.w(TAG, "crashApplication: trying to crash self!");
3727                    return;
3728                }
3729                long ident = Binder.clearCallingIdentity();
3730                try {
3731                    proc.thread.scheduleCrash(message);
3732                } catch (RemoteException e) {
3733                }
3734                Binder.restoreCallingIdentity(ident);
3735            }
3736        }
3737    }
3738
3739    @Override
3740    public final void finishSubActivity(IBinder token, String resultWho,
3741            int requestCode) {
3742        synchronized(this) {
3743            final long origId = Binder.clearCallingIdentity();
3744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3745            if (r != null) {
3746                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3747            }
3748            Binder.restoreCallingIdentity(origId);
3749        }
3750    }
3751
3752    @Override
3753    public boolean finishActivityAffinity(IBinder token) {
3754        synchronized(this) {
3755            final long origId = Binder.clearCallingIdentity();
3756            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3757            boolean res = false;
3758            if (r != null) {
3759                res = r.task.stack.finishActivityAffinityLocked(r);
3760            }
3761            Binder.restoreCallingIdentity(origId);
3762            return res;
3763        }
3764    }
3765
3766    @Override
3767    public boolean willActivityBeVisible(IBinder token) {
3768        synchronized(this) {
3769            ActivityStack stack = ActivityRecord.getStackLocked(token);
3770            if (stack != null) {
3771                return stack.willActivityBeVisibleLocked(token);
3772            }
3773            return false;
3774        }
3775    }
3776
3777    @Override
3778    public void overridePendingTransition(IBinder token, String packageName,
3779            int enterAnim, int exitAnim) {
3780        synchronized(this) {
3781            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3782            if (self == null) {
3783                return;
3784            }
3785
3786            final long origId = Binder.clearCallingIdentity();
3787
3788            if (self.state == ActivityState.RESUMED
3789                    || self.state == ActivityState.PAUSING) {
3790                mWindowManager.overridePendingAppTransition(packageName,
3791                        enterAnim, exitAnim, null);
3792            }
3793
3794            Binder.restoreCallingIdentity(origId);
3795        }
3796    }
3797
3798    /**
3799     * Main function for removing an existing process from the activity manager
3800     * as a result of that process going away.  Clears out all connections
3801     * to the process.
3802     */
3803    private final void handleAppDiedLocked(ProcessRecord app,
3804            boolean restarting, boolean allowRestart) {
3805        int pid = app.pid;
3806        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3807        if (!restarting) {
3808            removeLruProcessLocked(app);
3809            if (pid > 0) {
3810                ProcessList.remove(pid);
3811            }
3812        }
3813
3814        if (mProfileProc == app) {
3815            clearProfilerLocked();
3816        }
3817
3818        // Remove this application's activities from active lists.
3819        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3820
3821        app.activities.clear();
3822
3823        if (app.instrumentationClass != null) {
3824            Slog.w(TAG, "Crash of app " + app.processName
3825                  + " running instrumentation " + app.instrumentationClass);
3826            Bundle info = new Bundle();
3827            info.putString("shortMsg", "Process crashed.");
3828            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3829        }
3830
3831        if (!restarting) {
3832            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3833                // If there was nothing to resume, and we are not already
3834                // restarting this process, but there is a visible activity that
3835                // is hosted by the process...  then make sure all visible
3836                // activities are running, taking care of restarting this
3837                // process.
3838                if (hasVisibleActivities) {
3839                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3840                }
3841            }
3842        }
3843    }
3844
3845    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3846        IBinder threadBinder = thread.asBinder();
3847        // Find the application record.
3848        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3849            ProcessRecord rec = mLruProcesses.get(i);
3850            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3851                return i;
3852            }
3853        }
3854        return -1;
3855    }
3856
3857    final ProcessRecord getRecordForAppLocked(
3858            IApplicationThread thread) {
3859        if (thread == null) {
3860            return null;
3861        }
3862
3863        int appIndex = getLRURecordIndexForAppLocked(thread);
3864        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3865    }
3866
3867    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3868        // If there are no longer any background processes running,
3869        // and the app that died was not running instrumentation,
3870        // then tell everyone we are now low on memory.
3871        boolean haveBg = false;
3872        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3873            ProcessRecord rec = mLruProcesses.get(i);
3874            if (rec.thread != null
3875                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3876                haveBg = true;
3877                break;
3878            }
3879        }
3880
3881        if (!haveBg) {
3882            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3883            if (doReport) {
3884                long now = SystemClock.uptimeMillis();
3885                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3886                    doReport = false;
3887                } else {
3888                    mLastMemUsageReportTime = now;
3889                }
3890            }
3891            final ArrayList<ProcessMemInfo> memInfos
3892                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3893            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3894            long now = SystemClock.uptimeMillis();
3895            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3896                ProcessRecord rec = mLruProcesses.get(i);
3897                if (rec == dyingProc || rec.thread == null) {
3898                    continue;
3899                }
3900                if (doReport) {
3901                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3902                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3903                }
3904                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3905                    // The low memory report is overriding any current
3906                    // state for a GC request.  Make sure to do
3907                    // heavy/important/visible/foreground processes first.
3908                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3909                        rec.lastRequestedGc = 0;
3910                    } else {
3911                        rec.lastRequestedGc = rec.lastLowMemory;
3912                    }
3913                    rec.reportLowMemory = true;
3914                    rec.lastLowMemory = now;
3915                    mProcessesToGc.remove(rec);
3916                    addProcessToGcListLocked(rec);
3917                }
3918            }
3919            if (doReport) {
3920                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3921                mHandler.sendMessage(msg);
3922            }
3923            scheduleAppGcsLocked();
3924        }
3925    }
3926
3927    final void appDiedLocked(ProcessRecord app, int pid,
3928            IApplicationThread thread) {
3929
3930        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3931        synchronized (stats) {
3932            stats.noteProcessDiedLocked(app.info.uid, pid);
3933        }
3934
3935        // Clean up already done if the process has been re-started.
3936        if (app.pid == pid && app.thread != null &&
3937                app.thread.asBinder() == thread.asBinder()) {
3938            boolean doLowMem = app.instrumentationClass == null;
3939            boolean doOomAdj = doLowMem;
3940            if (!app.killedByAm) {
3941                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3942                        + ") has died.");
3943                mAllowLowerMemLevel = true;
3944            } else {
3945                // Note that we always want to do oom adj to update our state with the
3946                // new number of procs.
3947                mAllowLowerMemLevel = false;
3948                doLowMem = false;
3949            }
3950            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3951            if (DEBUG_CLEANUP) Slog.v(
3952                TAG, "Dying app: " + app + ", pid: " + pid
3953                + ", thread: " + thread.asBinder());
3954            handleAppDiedLocked(app, false, true);
3955
3956            if (doOomAdj) {
3957                updateOomAdjLocked();
3958            }
3959            if (doLowMem) {
3960                doLowMemReportIfNeededLocked(app);
3961            }
3962        } else if (app.pid != pid) {
3963            // A new process has already been started.
3964            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3965                    + ") has died and restarted (pid " + app.pid + ").");
3966            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3967        } else if (DEBUG_PROCESSES) {
3968            Slog.d(TAG, "Received spurious death notification for thread "
3969                    + thread.asBinder());
3970        }
3971    }
3972
3973    /**
3974     * If a stack trace dump file is configured, dump process stack traces.
3975     * @param clearTraces causes the dump file to be erased prior to the new
3976     *    traces being written, if true; when false, the new traces will be
3977     *    appended to any existing file content.
3978     * @param firstPids of dalvik VM processes to dump stack traces for first
3979     * @param lastPids of dalvik VM processes to dump stack traces for last
3980     * @param nativeProcs optional list of native process names to dump stack crawls
3981     * @return file containing stack traces, or null if no dump file is configured
3982     */
3983    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3984            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3985        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3986        if (tracesPath == null || tracesPath.length() == 0) {
3987            return null;
3988        }
3989
3990        File tracesFile = new File(tracesPath);
3991        try {
3992            File tracesDir = tracesFile.getParentFile();
3993            if (!tracesDir.exists()) {
3994                tracesFile.mkdirs();
3995                if (!SELinux.restorecon(tracesDir)) {
3996                    return null;
3997                }
3998            }
3999            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4000
4001            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4002            tracesFile.createNewFile();
4003            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4004        } catch (IOException e) {
4005            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4006            return null;
4007        }
4008
4009        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4010        return tracesFile;
4011    }
4012
4013    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4014            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4015        // Use a FileObserver to detect when traces finish writing.
4016        // The order of traces is considered important to maintain for legibility.
4017        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4018            @Override
4019            public synchronized void onEvent(int event, String path) { notify(); }
4020        };
4021
4022        try {
4023            observer.startWatching();
4024
4025            // First collect all of the stacks of the most important pids.
4026            if (firstPids != null) {
4027                try {
4028                    int num = firstPids.size();
4029                    for (int i = 0; i < num; i++) {
4030                        synchronized (observer) {
4031                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4032                            observer.wait(200);  // Wait for write-close, give up after 200msec
4033                        }
4034                    }
4035                } catch (InterruptedException e) {
4036                    Log.wtf(TAG, e);
4037                }
4038            }
4039
4040            // Next collect the stacks of the native pids
4041            if (nativeProcs != null) {
4042                int[] pids = Process.getPidsForCommands(nativeProcs);
4043                if (pids != null) {
4044                    for (int pid : pids) {
4045                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4046                    }
4047                }
4048            }
4049
4050            // Lastly, measure CPU usage.
4051            if (processCpuTracker != null) {
4052                processCpuTracker.init();
4053                System.gc();
4054                processCpuTracker.update();
4055                try {
4056                    synchronized (processCpuTracker) {
4057                        processCpuTracker.wait(500); // measure over 1/2 second.
4058                    }
4059                } catch (InterruptedException e) {
4060                }
4061                processCpuTracker.update();
4062
4063                // We'll take the stack crawls of just the top apps using CPU.
4064                final int N = processCpuTracker.countWorkingStats();
4065                int numProcs = 0;
4066                for (int i=0; i<N && numProcs<5; i++) {
4067                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4068                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4069                        numProcs++;
4070                        try {
4071                            synchronized (observer) {
4072                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4073                                observer.wait(200);  // Wait for write-close, give up after 200msec
4074                            }
4075                        } catch (InterruptedException e) {
4076                            Log.wtf(TAG, e);
4077                        }
4078
4079                    }
4080                }
4081            }
4082        } finally {
4083            observer.stopWatching();
4084        }
4085    }
4086
4087    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4088        if (true || IS_USER_BUILD) {
4089            return;
4090        }
4091        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4092        if (tracesPath == null || tracesPath.length() == 0) {
4093            return;
4094        }
4095
4096        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4097        StrictMode.allowThreadDiskWrites();
4098        try {
4099            final File tracesFile = new File(tracesPath);
4100            final File tracesDir = tracesFile.getParentFile();
4101            final File tracesTmp = new File(tracesDir, "__tmp__");
4102            try {
4103                if (!tracesDir.exists()) {
4104                    tracesFile.mkdirs();
4105                    if (!SELinux.restorecon(tracesDir.getPath())) {
4106                        return;
4107                    }
4108                }
4109                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4110
4111                if (tracesFile.exists()) {
4112                    tracesTmp.delete();
4113                    tracesFile.renameTo(tracesTmp);
4114                }
4115                StringBuilder sb = new StringBuilder();
4116                Time tobj = new Time();
4117                tobj.set(System.currentTimeMillis());
4118                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4119                sb.append(": ");
4120                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4121                sb.append(" since ");
4122                sb.append(msg);
4123                FileOutputStream fos = new FileOutputStream(tracesFile);
4124                fos.write(sb.toString().getBytes());
4125                if (app == null) {
4126                    fos.write("\n*** No application process!".getBytes());
4127                }
4128                fos.close();
4129                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4130            } catch (IOException e) {
4131                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4132                return;
4133            }
4134
4135            if (app != null) {
4136                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4137                firstPids.add(app.pid);
4138                dumpStackTraces(tracesPath, firstPids, null, null, null);
4139            }
4140
4141            File lastTracesFile = null;
4142            File curTracesFile = null;
4143            for (int i=9; i>=0; i--) {
4144                String name = String.format(Locale.US, "slow%02d.txt", i);
4145                curTracesFile = new File(tracesDir, name);
4146                if (curTracesFile.exists()) {
4147                    if (lastTracesFile != null) {
4148                        curTracesFile.renameTo(lastTracesFile);
4149                    } else {
4150                        curTracesFile.delete();
4151                    }
4152                }
4153                lastTracesFile = curTracesFile;
4154            }
4155            tracesFile.renameTo(curTracesFile);
4156            if (tracesTmp.exists()) {
4157                tracesTmp.renameTo(tracesFile);
4158            }
4159        } finally {
4160            StrictMode.setThreadPolicy(oldPolicy);
4161        }
4162    }
4163
4164    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4165            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4166        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4167        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4168
4169        if (mController != null) {
4170            try {
4171                // 0 == continue, -1 = kill process immediately
4172                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4173                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4174            } catch (RemoteException e) {
4175                mController = null;
4176                Watchdog.getInstance().setActivityController(null);
4177            }
4178        }
4179
4180        long anrTime = SystemClock.uptimeMillis();
4181        if (MONITOR_CPU_USAGE) {
4182            updateCpuStatsNow();
4183        }
4184
4185        synchronized (this) {
4186            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4187            if (mShuttingDown) {
4188                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4189                return;
4190            } else if (app.notResponding) {
4191                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4192                return;
4193            } else if (app.crashing) {
4194                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4195                return;
4196            }
4197
4198            // In case we come through here for the same app before completing
4199            // this one, mark as anring now so we will bail out.
4200            app.notResponding = true;
4201
4202            // Log the ANR to the event log.
4203            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4204                    app.processName, app.info.flags, annotation);
4205
4206            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4207            firstPids.add(app.pid);
4208
4209            int parentPid = app.pid;
4210            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4211            if (parentPid != app.pid) firstPids.add(parentPid);
4212
4213            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4214
4215            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4216                ProcessRecord r = mLruProcesses.get(i);
4217                if (r != null && r.thread != null) {
4218                    int pid = r.pid;
4219                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4220                        if (r.persistent) {
4221                            firstPids.add(pid);
4222                        } else {
4223                            lastPids.put(pid, Boolean.TRUE);
4224                        }
4225                    }
4226                }
4227            }
4228        }
4229
4230        // Log the ANR to the main log.
4231        StringBuilder info = new StringBuilder();
4232        info.setLength(0);
4233        info.append("ANR in ").append(app.processName);
4234        if (activity != null && activity.shortComponentName != null) {
4235            info.append(" (").append(activity.shortComponentName).append(")");
4236        }
4237        info.append("\n");
4238        info.append("PID: ").append(app.pid).append("\n");
4239        if (annotation != null) {
4240            info.append("Reason: ").append(annotation).append("\n");
4241        }
4242        if (parent != null && parent != activity) {
4243            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4244        }
4245
4246        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4247
4248        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4249                NATIVE_STACKS_OF_INTEREST);
4250
4251        String cpuInfo = null;
4252        if (MONITOR_CPU_USAGE) {
4253            updateCpuStatsNow();
4254            synchronized (mProcessCpuThread) {
4255                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4256            }
4257            info.append(processCpuTracker.printCurrentLoad());
4258            info.append(cpuInfo);
4259        }
4260
4261        info.append(processCpuTracker.printCurrentState(anrTime));
4262
4263        Slog.e(TAG, info.toString());
4264        if (tracesFile == null) {
4265            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4266            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4267        }
4268
4269        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4270                cpuInfo, tracesFile, null);
4271
4272        if (mController != null) {
4273            try {
4274                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4275                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4276                if (res != 0) {
4277                    if (res < 0 && app.pid != MY_PID) {
4278                        Process.killProcess(app.pid);
4279                    } else {
4280                        synchronized (this) {
4281                            mServices.scheduleServiceTimeoutLocked(app);
4282                        }
4283                    }
4284                    return;
4285                }
4286            } catch (RemoteException e) {
4287                mController = null;
4288                Watchdog.getInstance().setActivityController(null);
4289            }
4290        }
4291
4292        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4293        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4294                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4295
4296        synchronized (this) {
4297            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4298                killUnneededProcessLocked(app, "background ANR");
4299                return;
4300            }
4301
4302            // Set the app's notResponding state, and look up the errorReportReceiver
4303            makeAppNotRespondingLocked(app,
4304                    activity != null ? activity.shortComponentName : null,
4305                    annotation != null ? "ANR " + annotation : "ANR",
4306                    info.toString());
4307
4308            // Bring up the infamous App Not Responding dialog
4309            Message msg = Message.obtain();
4310            HashMap<String, Object> map = new HashMap<String, Object>();
4311            msg.what = SHOW_NOT_RESPONDING_MSG;
4312            msg.obj = map;
4313            msg.arg1 = aboveSystem ? 1 : 0;
4314            map.put("app", app);
4315            if (activity != null) {
4316                map.put("activity", activity);
4317            }
4318
4319            mHandler.sendMessage(msg);
4320        }
4321    }
4322
4323    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4324        if (!mLaunchWarningShown) {
4325            mLaunchWarningShown = true;
4326            mHandler.post(new Runnable() {
4327                @Override
4328                public void run() {
4329                    synchronized (ActivityManagerService.this) {
4330                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4331                        d.show();
4332                        mHandler.postDelayed(new Runnable() {
4333                            @Override
4334                            public void run() {
4335                                synchronized (ActivityManagerService.this) {
4336                                    d.dismiss();
4337                                    mLaunchWarningShown = false;
4338                                }
4339                            }
4340                        }, 4000);
4341                    }
4342                }
4343            });
4344        }
4345    }
4346
4347    @Override
4348    public boolean clearApplicationUserData(final String packageName,
4349            final IPackageDataObserver observer, int userId) {
4350        enforceNotIsolatedCaller("clearApplicationUserData");
4351        int uid = Binder.getCallingUid();
4352        int pid = Binder.getCallingPid();
4353        userId = handleIncomingUser(pid, uid,
4354                userId, false, true, "clearApplicationUserData", null);
4355        long callingId = Binder.clearCallingIdentity();
4356        try {
4357            IPackageManager pm = AppGlobals.getPackageManager();
4358            int pkgUid = -1;
4359            synchronized(this) {
4360                try {
4361                    pkgUid = pm.getPackageUid(packageName, userId);
4362                } catch (RemoteException e) {
4363                }
4364                if (pkgUid == -1) {
4365                    Slog.w(TAG, "Invalid packageName: " + packageName);
4366                    if (observer != null) {
4367                        try {
4368                            observer.onRemoveCompleted(packageName, false);
4369                        } catch (RemoteException e) {
4370                            Slog.i(TAG, "Observer no longer exists.");
4371                        }
4372                    }
4373                    return false;
4374                }
4375                if (uid == pkgUid || checkComponentPermission(
4376                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4377                        pid, uid, -1, true)
4378                        == PackageManager.PERMISSION_GRANTED) {
4379                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4380                } else {
4381                    throw new SecurityException("PID " + pid + " does not have permission "
4382                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4383                                    + " of package " + packageName);
4384                }
4385            }
4386
4387            try {
4388                // Clear application user data
4389                pm.clearApplicationUserData(packageName, observer, userId);
4390
4391                // Remove all permissions granted from/to this package
4392                removeUriPermissionsForPackageLocked(packageName, userId, true);
4393
4394                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4395                        Uri.fromParts("package", packageName, null));
4396                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4397                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4398                        null, null, 0, null, null, null, false, false, userId);
4399            } catch (RemoteException e) {
4400            }
4401        } finally {
4402            Binder.restoreCallingIdentity(callingId);
4403        }
4404        return true;
4405    }
4406
4407    @Override
4408    public void killBackgroundProcesses(final String packageName, int userId) {
4409        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4410                != PackageManager.PERMISSION_GRANTED &&
4411                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4412                        != PackageManager.PERMISSION_GRANTED) {
4413            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4414                    + Binder.getCallingPid()
4415                    + ", uid=" + Binder.getCallingUid()
4416                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4417            Slog.w(TAG, msg);
4418            throw new SecurityException(msg);
4419        }
4420
4421        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4422                userId, true, true, "killBackgroundProcesses", null);
4423        long callingId = Binder.clearCallingIdentity();
4424        try {
4425            IPackageManager pm = AppGlobals.getPackageManager();
4426            synchronized(this) {
4427                int appId = -1;
4428                try {
4429                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4430                } catch (RemoteException e) {
4431                }
4432                if (appId == -1) {
4433                    Slog.w(TAG, "Invalid packageName: " + packageName);
4434                    return;
4435                }
4436                killPackageProcessesLocked(packageName, appId, userId,
4437                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4438            }
4439        } finally {
4440            Binder.restoreCallingIdentity(callingId);
4441        }
4442    }
4443
4444    @Override
4445    public void killAllBackgroundProcesses() {
4446        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4447                != PackageManager.PERMISSION_GRANTED) {
4448            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4449                    + Binder.getCallingPid()
4450                    + ", uid=" + Binder.getCallingUid()
4451                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4452            Slog.w(TAG, msg);
4453            throw new SecurityException(msg);
4454        }
4455
4456        long callingId = Binder.clearCallingIdentity();
4457        try {
4458            synchronized(this) {
4459                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4460                final int NP = mProcessNames.getMap().size();
4461                for (int ip=0; ip<NP; ip++) {
4462                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4463                    final int NA = apps.size();
4464                    for (int ia=0; ia<NA; ia++) {
4465                        ProcessRecord app = apps.valueAt(ia);
4466                        if (app.persistent) {
4467                            // we don't kill persistent processes
4468                            continue;
4469                        }
4470                        if (app.removed) {
4471                            procs.add(app);
4472                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4473                            app.removed = true;
4474                            procs.add(app);
4475                        }
4476                    }
4477                }
4478
4479                int N = procs.size();
4480                for (int i=0; i<N; i++) {
4481                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4482                }
4483                mAllowLowerMemLevel = true;
4484                updateOomAdjLocked();
4485                doLowMemReportIfNeededLocked(null);
4486            }
4487        } finally {
4488            Binder.restoreCallingIdentity(callingId);
4489        }
4490    }
4491
4492    @Override
4493    public void forceStopPackage(final String packageName, int userId) {
4494        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4495                != PackageManager.PERMISSION_GRANTED) {
4496            String msg = "Permission Denial: forceStopPackage() from pid="
4497                    + Binder.getCallingPid()
4498                    + ", uid=" + Binder.getCallingUid()
4499                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4500            Slog.w(TAG, msg);
4501            throw new SecurityException(msg);
4502        }
4503        final int callingPid = Binder.getCallingPid();
4504        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4505                userId, true, true, "forceStopPackage", null);
4506        long callingId = Binder.clearCallingIdentity();
4507        try {
4508            IPackageManager pm = AppGlobals.getPackageManager();
4509            synchronized(this) {
4510                int[] users = userId == UserHandle.USER_ALL
4511                        ? getUsersLocked() : new int[] { userId };
4512                for (int user : users) {
4513                    int pkgUid = -1;
4514                    try {
4515                        pkgUid = pm.getPackageUid(packageName, user);
4516                    } catch (RemoteException e) {
4517                    }
4518                    if (pkgUid == -1) {
4519                        Slog.w(TAG, "Invalid packageName: " + packageName);
4520                        continue;
4521                    }
4522                    try {
4523                        pm.setPackageStoppedState(packageName, true, user);
4524                    } catch (RemoteException e) {
4525                    } catch (IllegalArgumentException e) {
4526                        Slog.w(TAG, "Failed trying to unstop package "
4527                                + packageName + ": " + e);
4528                    }
4529                    if (isUserRunningLocked(user, false)) {
4530                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4531                    }
4532                }
4533            }
4534        } finally {
4535            Binder.restoreCallingIdentity(callingId);
4536        }
4537    }
4538
4539    /*
4540     * The pkg name and app id have to be specified.
4541     */
4542    @Override
4543    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4544        if (pkg == null) {
4545            return;
4546        }
4547        // Make sure the uid is valid.
4548        if (appid < 0) {
4549            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4550            return;
4551        }
4552        int callerUid = Binder.getCallingUid();
4553        // Only the system server can kill an application
4554        if (callerUid == Process.SYSTEM_UID) {
4555            // Post an aysnc message to kill the application
4556            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4557            msg.arg1 = appid;
4558            msg.arg2 = 0;
4559            Bundle bundle = new Bundle();
4560            bundle.putString("pkg", pkg);
4561            bundle.putString("reason", reason);
4562            msg.obj = bundle;
4563            mHandler.sendMessage(msg);
4564        } else {
4565            throw new SecurityException(callerUid + " cannot kill pkg: " +
4566                    pkg);
4567        }
4568    }
4569
4570    @Override
4571    public void closeSystemDialogs(String reason) {
4572        enforceNotIsolatedCaller("closeSystemDialogs");
4573
4574        final int pid = Binder.getCallingPid();
4575        final int uid = Binder.getCallingUid();
4576        final long origId = Binder.clearCallingIdentity();
4577        try {
4578            synchronized (this) {
4579                // Only allow this from foreground processes, so that background
4580                // applications can't abuse it to prevent system UI from being shown.
4581                if (uid >= Process.FIRST_APPLICATION_UID) {
4582                    ProcessRecord proc;
4583                    synchronized (mPidsSelfLocked) {
4584                        proc = mPidsSelfLocked.get(pid);
4585                    }
4586                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4587                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4588                                + " from background process " + proc);
4589                        return;
4590                    }
4591                }
4592                closeSystemDialogsLocked(reason);
4593            }
4594        } finally {
4595            Binder.restoreCallingIdentity(origId);
4596        }
4597    }
4598
4599    void closeSystemDialogsLocked(String reason) {
4600        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4601        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4602                | Intent.FLAG_RECEIVER_FOREGROUND);
4603        if (reason != null) {
4604            intent.putExtra("reason", reason);
4605        }
4606        mWindowManager.closeSystemDialogs(reason);
4607
4608        mStackSupervisor.closeSystemDialogsLocked();
4609
4610        broadcastIntentLocked(null, null, intent, null,
4611                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4612                Process.SYSTEM_UID, UserHandle.USER_ALL);
4613    }
4614
4615    @Override
4616    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4617        enforceNotIsolatedCaller("getProcessMemoryInfo");
4618        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4619        for (int i=pids.length-1; i>=0; i--) {
4620            ProcessRecord proc;
4621            int oomAdj;
4622            synchronized (this) {
4623                synchronized (mPidsSelfLocked) {
4624                    proc = mPidsSelfLocked.get(pids[i]);
4625                    oomAdj = proc != null ? proc.setAdj : 0;
4626                }
4627            }
4628            infos[i] = new Debug.MemoryInfo();
4629            Debug.getMemoryInfo(pids[i], infos[i]);
4630            if (proc != null) {
4631                synchronized (this) {
4632                    if (proc.thread != null && proc.setAdj == oomAdj) {
4633                        // Record this for posterity if the process has been stable.
4634                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4635                                infos[i].getTotalUss(), false, proc.pkgList);
4636                    }
4637                }
4638            }
4639        }
4640        return infos;
4641    }
4642
4643    @Override
4644    public long[] getProcessPss(int[] pids) {
4645        enforceNotIsolatedCaller("getProcessPss");
4646        long[] pss = new long[pids.length];
4647        for (int i=pids.length-1; i>=0; i--) {
4648            ProcessRecord proc;
4649            int oomAdj;
4650            synchronized (this) {
4651                synchronized (mPidsSelfLocked) {
4652                    proc = mPidsSelfLocked.get(pids[i]);
4653                    oomAdj = proc != null ? proc.setAdj : 0;
4654                }
4655            }
4656            long[] tmpUss = new long[1];
4657            pss[i] = Debug.getPss(pids[i], tmpUss);
4658            if (proc != null) {
4659                synchronized (this) {
4660                    if (proc.thread != null && proc.setAdj == oomAdj) {
4661                        // Record this for posterity if the process has been stable.
4662                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4663                    }
4664                }
4665            }
4666        }
4667        return pss;
4668    }
4669
4670    @Override
4671    public void killApplicationProcess(String processName, int uid) {
4672        if (processName == null) {
4673            return;
4674        }
4675
4676        int callerUid = Binder.getCallingUid();
4677        // Only the system server can kill an application
4678        if (callerUid == Process.SYSTEM_UID) {
4679            synchronized (this) {
4680                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4681                if (app != null && app.thread != null) {
4682                    try {
4683                        app.thread.scheduleSuicide();
4684                    } catch (RemoteException e) {
4685                        // If the other end already died, then our work here is done.
4686                    }
4687                } else {
4688                    Slog.w(TAG, "Process/uid not found attempting kill of "
4689                            + processName + " / " + uid);
4690                }
4691            }
4692        } else {
4693            throw new SecurityException(callerUid + " cannot kill app process: " +
4694                    processName);
4695        }
4696    }
4697
4698    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4699        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4700                false, true, false, false, UserHandle.getUserId(uid), reason);
4701        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4702                Uri.fromParts("package", packageName, null));
4703        if (!mProcessesReady) {
4704            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4705                    | Intent.FLAG_RECEIVER_FOREGROUND);
4706        }
4707        intent.putExtra(Intent.EXTRA_UID, uid);
4708        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4709        broadcastIntentLocked(null, null, intent,
4710                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4711                false, false,
4712                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4713    }
4714
4715    private void forceStopUserLocked(int userId, String reason) {
4716        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4717        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4718        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4719                | Intent.FLAG_RECEIVER_FOREGROUND);
4720        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4721        broadcastIntentLocked(null, null, intent,
4722                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4723                false, false,
4724                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4725    }
4726
4727    private final boolean killPackageProcessesLocked(String packageName, int appId,
4728            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4729            boolean doit, boolean evenPersistent, String reason) {
4730        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4731
4732        // Remove all processes this package may have touched: all with the
4733        // same UID (except for the system or root user), and all whose name
4734        // matches the package name.
4735        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4736        final int NP = mProcessNames.getMap().size();
4737        for (int ip=0; ip<NP; ip++) {
4738            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4739            final int NA = apps.size();
4740            for (int ia=0; ia<NA; ia++) {
4741                ProcessRecord app = apps.valueAt(ia);
4742                if (app.persistent && !evenPersistent) {
4743                    // we don't kill persistent processes
4744                    continue;
4745                }
4746                if (app.removed) {
4747                    if (doit) {
4748                        procs.add(app);
4749                    }
4750                    continue;
4751                }
4752
4753                // Skip process if it doesn't meet our oom adj requirement.
4754                if (app.setAdj < minOomAdj) {
4755                    continue;
4756                }
4757
4758                // If no package is specified, we call all processes under the
4759                // give user id.
4760                if (packageName == null) {
4761                    if (app.userId != userId) {
4762                        continue;
4763                    }
4764                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4765                        continue;
4766                    }
4767                // Package has been specified, we want to hit all processes
4768                // that match it.  We need to qualify this by the processes
4769                // that are running under the specified app and user ID.
4770                } else {
4771                    if (UserHandle.getAppId(app.uid) != appId) {
4772                        continue;
4773                    }
4774                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4775                        continue;
4776                    }
4777                    if (!app.pkgList.containsKey(packageName)) {
4778                        continue;
4779                    }
4780                }
4781
4782                // Process has passed all conditions, kill it!
4783                if (!doit) {
4784                    return true;
4785                }
4786                app.removed = true;
4787                procs.add(app);
4788            }
4789        }
4790
4791        int N = procs.size();
4792        for (int i=0; i<N; i++) {
4793            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4794        }
4795        updateOomAdjLocked();
4796        return N > 0;
4797    }
4798
4799    private final boolean forceStopPackageLocked(String name, int appId,
4800            boolean callerWillRestart, boolean purgeCache, boolean doit,
4801            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4802        int i;
4803        int N;
4804
4805        if (userId == UserHandle.USER_ALL && name == null) {
4806            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4807        }
4808
4809        if (appId < 0 && name != null) {
4810            try {
4811                appId = UserHandle.getAppId(
4812                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4813            } catch (RemoteException e) {
4814            }
4815        }
4816
4817        if (doit) {
4818            if (name != null) {
4819                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4820                        + " user=" + userId + ": " + reason);
4821            } else {
4822                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4823            }
4824
4825            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4826            for (int ip=pmap.size()-1; ip>=0; ip--) {
4827                SparseArray<Long> ba = pmap.valueAt(ip);
4828                for (i=ba.size()-1; i>=0; i--) {
4829                    boolean remove = false;
4830                    final int entUid = ba.keyAt(i);
4831                    if (name != null) {
4832                        if (userId == UserHandle.USER_ALL) {
4833                            if (UserHandle.getAppId(entUid) == appId) {
4834                                remove = true;
4835                            }
4836                        } else {
4837                            if (entUid == UserHandle.getUid(userId, appId)) {
4838                                remove = true;
4839                            }
4840                        }
4841                    } else if (UserHandle.getUserId(entUid) == userId) {
4842                        remove = true;
4843                    }
4844                    if (remove) {
4845                        ba.removeAt(i);
4846                    }
4847                }
4848                if (ba.size() == 0) {
4849                    pmap.removeAt(ip);
4850                }
4851            }
4852        }
4853
4854        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4855                -100, callerWillRestart, true, doit, evenPersistent,
4856                name == null ? ("stop user " + userId) : ("stop " + name));
4857
4858        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4859            if (!doit) {
4860                return true;
4861            }
4862            didSomething = true;
4863        }
4864
4865        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4866            if (!doit) {
4867                return true;
4868            }
4869            didSomething = true;
4870        }
4871
4872        if (name == null) {
4873            // Remove all sticky broadcasts from this user.
4874            mStickyBroadcasts.remove(userId);
4875        }
4876
4877        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4878        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4879                userId, providers)) {
4880            if (!doit) {
4881                return true;
4882            }
4883            didSomething = true;
4884        }
4885        N = providers.size();
4886        for (i=0; i<N; i++) {
4887            removeDyingProviderLocked(null, providers.get(i), true);
4888        }
4889
4890        // Remove transient permissions granted from/to this package/user
4891        removeUriPermissionsForPackageLocked(name, userId, false);
4892
4893        if (name == null || uninstalling) {
4894            // Remove pending intents.  For now we only do this when force
4895            // stopping users, because we have some problems when doing this
4896            // for packages -- app widgets are not currently cleaned up for
4897            // such packages, so they can be left with bad pending intents.
4898            if (mIntentSenderRecords.size() > 0) {
4899                Iterator<WeakReference<PendingIntentRecord>> it
4900                        = mIntentSenderRecords.values().iterator();
4901                while (it.hasNext()) {
4902                    WeakReference<PendingIntentRecord> wpir = it.next();
4903                    if (wpir == null) {
4904                        it.remove();
4905                        continue;
4906                    }
4907                    PendingIntentRecord pir = wpir.get();
4908                    if (pir == null) {
4909                        it.remove();
4910                        continue;
4911                    }
4912                    if (name == null) {
4913                        // Stopping user, remove all objects for the user.
4914                        if (pir.key.userId != userId) {
4915                            // Not the same user, skip it.
4916                            continue;
4917                        }
4918                    } else {
4919                        if (UserHandle.getAppId(pir.uid) != appId) {
4920                            // Different app id, skip it.
4921                            continue;
4922                        }
4923                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4924                            // Different user, skip it.
4925                            continue;
4926                        }
4927                        if (!pir.key.packageName.equals(name)) {
4928                            // Different package, skip it.
4929                            continue;
4930                        }
4931                    }
4932                    if (!doit) {
4933                        return true;
4934                    }
4935                    didSomething = true;
4936                    it.remove();
4937                    pir.canceled = true;
4938                    if (pir.key.activity != null) {
4939                        pir.key.activity.pendingResults.remove(pir.ref);
4940                    }
4941                }
4942            }
4943        }
4944
4945        if (doit) {
4946            if (purgeCache && name != null) {
4947                AttributeCache ac = AttributeCache.instance();
4948                if (ac != null) {
4949                    ac.removePackage(name);
4950                }
4951            }
4952            if (mBooted) {
4953                mStackSupervisor.resumeTopActivitiesLocked();
4954                mStackSupervisor.scheduleIdleLocked();
4955            }
4956        }
4957
4958        return didSomething;
4959    }
4960
4961    private final boolean removeProcessLocked(ProcessRecord app,
4962            boolean callerWillRestart, boolean allowRestart, String reason) {
4963        final String name = app.processName;
4964        final int uid = app.uid;
4965        if (DEBUG_PROCESSES) Slog.d(
4966            TAG, "Force removing proc " + app.toShortString() + " (" + name
4967            + "/" + uid + ")");
4968
4969        mProcessNames.remove(name, uid);
4970        mIsolatedProcesses.remove(app.uid);
4971        if (mHeavyWeightProcess == app) {
4972            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4973                    mHeavyWeightProcess.userId, 0));
4974            mHeavyWeightProcess = null;
4975        }
4976        boolean needRestart = false;
4977        if (app.pid > 0 && app.pid != MY_PID) {
4978            int pid = app.pid;
4979            synchronized (mPidsSelfLocked) {
4980                mPidsSelfLocked.remove(pid);
4981                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4982            }
4983            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4984                    app.processName, app.info.uid);
4985            if (app.isolated) {
4986                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4987            }
4988            killUnneededProcessLocked(app, reason);
4989            handleAppDiedLocked(app, true, allowRestart);
4990            removeLruProcessLocked(app);
4991
4992            if (app.persistent && !app.isolated) {
4993                if (!callerWillRestart) {
4994                    addAppLocked(app.info, false);
4995                } else {
4996                    needRestart = true;
4997                }
4998            }
4999        } else {
5000            mRemovedProcesses.add(app);
5001        }
5002
5003        return needRestart;
5004    }
5005
5006    private final void processStartTimedOutLocked(ProcessRecord app) {
5007        final int pid = app.pid;
5008        boolean gone = false;
5009        synchronized (mPidsSelfLocked) {
5010            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5011            if (knownApp != null && knownApp.thread == null) {
5012                mPidsSelfLocked.remove(pid);
5013                gone = true;
5014            }
5015        }
5016
5017        if (gone) {
5018            Slog.w(TAG, "Process " + app + " failed to attach");
5019            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5020                    pid, app.uid, app.processName);
5021            mProcessNames.remove(app.processName, app.uid);
5022            mIsolatedProcesses.remove(app.uid);
5023            if (mHeavyWeightProcess == app) {
5024                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5025                        mHeavyWeightProcess.userId, 0));
5026                mHeavyWeightProcess = null;
5027            }
5028            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5029                    app.processName, app.info.uid);
5030            if (app.isolated) {
5031                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5032            }
5033            // Take care of any launching providers waiting for this process.
5034            checkAppInLaunchingProvidersLocked(app, true);
5035            // Take care of any services that are waiting for the process.
5036            mServices.processStartTimedOutLocked(app);
5037            killUnneededProcessLocked(app, "start timeout");
5038            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5039                Slog.w(TAG, "Unattached app died before backup, skipping");
5040                try {
5041                    IBackupManager bm = IBackupManager.Stub.asInterface(
5042                            ServiceManager.getService(Context.BACKUP_SERVICE));
5043                    bm.agentDisconnected(app.info.packageName);
5044                } catch (RemoteException e) {
5045                    // Can't happen; the backup manager is local
5046                }
5047            }
5048            if (isPendingBroadcastProcessLocked(pid)) {
5049                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5050                skipPendingBroadcastLocked(pid);
5051            }
5052        } else {
5053            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5054        }
5055    }
5056
5057    private final boolean attachApplicationLocked(IApplicationThread thread,
5058            int pid) {
5059
5060        // Find the application record that is being attached...  either via
5061        // the pid if we are running in multiple processes, or just pull the
5062        // next app record if we are emulating process with anonymous threads.
5063        ProcessRecord app;
5064        if (pid != MY_PID && pid >= 0) {
5065            synchronized (mPidsSelfLocked) {
5066                app = mPidsSelfLocked.get(pid);
5067            }
5068        } else {
5069            app = null;
5070        }
5071
5072        if (app == null) {
5073            Slog.w(TAG, "No pending application record for pid " + pid
5074                    + " (IApplicationThread " + thread + "); dropping process");
5075            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5076            if (pid > 0 && pid != MY_PID) {
5077                Process.killProcessQuiet(pid);
5078            } else {
5079                try {
5080                    thread.scheduleExit();
5081                } catch (Exception e) {
5082                    // Ignore exceptions.
5083                }
5084            }
5085            return false;
5086        }
5087
5088        // If this application record is still attached to a previous
5089        // process, clean it up now.
5090        if (app.thread != null) {
5091            handleAppDiedLocked(app, true, true);
5092        }
5093
5094        // Tell the process all about itself.
5095
5096        if (localLOGV) Slog.v(
5097                TAG, "Binding process pid " + pid + " to record " + app);
5098
5099        final String processName = app.processName;
5100        try {
5101            AppDeathRecipient adr = new AppDeathRecipient(
5102                    app, pid, thread);
5103            thread.asBinder().linkToDeath(adr, 0);
5104            app.deathRecipient = adr;
5105        } catch (RemoteException e) {
5106            app.resetPackageList(mProcessStats);
5107            startProcessLocked(app, "link fail", processName);
5108            return false;
5109        }
5110
5111        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5112
5113        app.makeActive(thread, mProcessStats);
5114        app.curAdj = app.setAdj = -100;
5115        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5116        app.forcingToForeground = null;
5117        updateProcessForegroundLocked(app, false, false);
5118        app.hasShownUi = false;
5119        app.debugging = false;
5120        app.cached = false;
5121
5122        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5123
5124        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5125        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5126
5127        if (!normalMode) {
5128            Slog.i(TAG, "Launching preboot mode app: " + app);
5129        }
5130
5131        if (localLOGV) Slog.v(
5132            TAG, "New app record " + app
5133            + " thread=" + thread.asBinder() + " pid=" + pid);
5134        try {
5135            int testMode = IApplicationThread.DEBUG_OFF;
5136            if (mDebugApp != null && mDebugApp.equals(processName)) {
5137                testMode = mWaitForDebugger
5138                    ? IApplicationThread.DEBUG_WAIT
5139                    : IApplicationThread.DEBUG_ON;
5140                app.debugging = true;
5141                if (mDebugTransient) {
5142                    mDebugApp = mOrigDebugApp;
5143                    mWaitForDebugger = mOrigWaitForDebugger;
5144                }
5145            }
5146            String profileFile = app.instrumentationProfileFile;
5147            ParcelFileDescriptor profileFd = null;
5148            boolean profileAutoStop = false;
5149            if (mProfileApp != null && mProfileApp.equals(processName)) {
5150                mProfileProc = app;
5151                profileFile = mProfileFile;
5152                profileFd = mProfileFd;
5153                profileAutoStop = mAutoStopProfiler;
5154            }
5155            boolean enableOpenGlTrace = false;
5156            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5157                enableOpenGlTrace = true;
5158                mOpenGlTraceApp = null;
5159            }
5160
5161            // If the app is being launched for restore or full backup, set it up specially
5162            boolean isRestrictedBackupMode = false;
5163            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5164                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5165                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5166                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5167            }
5168
5169            ensurePackageDexOpt(app.instrumentationInfo != null
5170                    ? app.instrumentationInfo.packageName
5171                    : app.info.packageName);
5172            if (app.instrumentationClass != null) {
5173                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5174            }
5175            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5176                    + processName + " with config " + mConfiguration);
5177            ApplicationInfo appInfo = app.instrumentationInfo != null
5178                    ? app.instrumentationInfo : app.info;
5179            app.compat = compatibilityInfoForPackageLocked(appInfo);
5180            if (profileFd != null) {
5181                profileFd = profileFd.dup();
5182            }
5183            thread.bindApplication(processName, appInfo, providers,
5184                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5185                    app.instrumentationArguments, app.instrumentationWatcher,
5186                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5187                    isRestrictedBackupMode || !normalMode, app.persistent,
5188                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5189                    mCoreSettingsObserver.getCoreSettingsLocked());
5190            updateLruProcessLocked(app, false, null);
5191            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5192        } catch (Exception e) {
5193            // todo: Yikes!  What should we do?  For now we will try to
5194            // start another process, but that could easily get us in
5195            // an infinite loop of restarting processes...
5196            Slog.w(TAG, "Exception thrown during bind!", e);
5197
5198            app.resetPackageList(mProcessStats);
5199            app.unlinkDeathRecipient();
5200            startProcessLocked(app, "bind fail", processName);
5201            return false;
5202        }
5203
5204        // Remove this record from the list of starting applications.
5205        mPersistentStartingProcesses.remove(app);
5206        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5207                "Attach application locked removing on hold: " + app);
5208        mProcessesOnHold.remove(app);
5209
5210        boolean badApp = false;
5211        boolean didSomething = false;
5212
5213        // See if the top visible activity is waiting to run in this process...
5214        if (normalMode) {
5215            try {
5216                if (mStackSupervisor.attachApplicationLocked(app)) {
5217                    didSomething = true;
5218                }
5219            } catch (Exception e) {
5220                badApp = true;
5221            }
5222        }
5223
5224        // Find any services that should be running in this process...
5225        if (!badApp) {
5226            try {
5227                didSomething |= mServices.attachApplicationLocked(app, processName);
5228            } catch (Exception e) {
5229                badApp = true;
5230            }
5231        }
5232
5233        // Check if a next-broadcast receiver is in this process...
5234        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5235            try {
5236                didSomething |= sendPendingBroadcastsLocked(app);
5237            } catch (Exception e) {
5238                // If the app died trying to launch the receiver we declare it 'bad'
5239                badApp = true;
5240            }
5241        }
5242
5243        // Check whether the next backup agent is in this process...
5244        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5245            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5246            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5247            try {
5248                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5249                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5250                        mBackupTarget.backupMode);
5251            } catch (Exception e) {
5252                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5253                e.printStackTrace();
5254            }
5255        }
5256
5257        if (badApp) {
5258            // todo: Also need to kill application to deal with all
5259            // kinds of exceptions.
5260            handleAppDiedLocked(app, false, true);
5261            return false;
5262        }
5263
5264        if (!didSomething) {
5265            updateOomAdjLocked();
5266        }
5267
5268        return true;
5269    }
5270
5271    @Override
5272    public final void attachApplication(IApplicationThread thread) {
5273        synchronized (this) {
5274            int callingPid = Binder.getCallingPid();
5275            final long origId = Binder.clearCallingIdentity();
5276            attachApplicationLocked(thread, callingPid);
5277            Binder.restoreCallingIdentity(origId);
5278        }
5279    }
5280
5281    @Override
5282    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5283        final long origId = Binder.clearCallingIdentity();
5284        synchronized (this) {
5285            ActivityStack stack = ActivityRecord.getStackLocked(token);
5286            if (stack != null) {
5287                ActivityRecord r =
5288                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5289                if (stopProfiling) {
5290                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5291                        try {
5292                            mProfileFd.close();
5293                        } catch (IOException e) {
5294                        }
5295                        clearProfilerLocked();
5296                    }
5297                }
5298            }
5299        }
5300        Binder.restoreCallingIdentity(origId);
5301    }
5302
5303    void enableScreenAfterBoot() {
5304        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5305                SystemClock.uptimeMillis());
5306        mWindowManager.enableScreenAfterBoot();
5307
5308        synchronized (this) {
5309            updateEventDispatchingLocked();
5310        }
5311    }
5312
5313    @Override
5314    public void showBootMessage(final CharSequence msg, final boolean always) {
5315        enforceNotIsolatedCaller("showBootMessage");
5316        mWindowManager.showBootMessage(msg, always);
5317    }
5318
5319    @Override
5320    public void dismissKeyguardOnNextActivity() {
5321        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5322        final long token = Binder.clearCallingIdentity();
5323        try {
5324            synchronized (this) {
5325                if (DEBUG_LOCKSCREEN) logLockScreen("");
5326                if (mLockScreenShown) {
5327                    mLockScreenShown = false;
5328                    comeOutOfSleepIfNeededLocked();
5329                }
5330                mStackSupervisor.setDismissKeyguard(true);
5331            }
5332        } finally {
5333            Binder.restoreCallingIdentity(token);
5334        }
5335    }
5336
5337    final void finishBooting() {
5338        // Register receivers to handle package update events
5339        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5340
5341        synchronized (this) {
5342            // Ensure that any processes we had put on hold are now started
5343            // up.
5344            final int NP = mProcessesOnHold.size();
5345            if (NP > 0) {
5346                ArrayList<ProcessRecord> procs =
5347                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5348                for (int ip=0; ip<NP; ip++) {
5349                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5350                            + procs.get(ip));
5351                    startProcessLocked(procs.get(ip), "on-hold", null);
5352                }
5353            }
5354
5355            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5356                // Start looking for apps that are abusing wake locks.
5357                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5358                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5359                // Tell anyone interested that we are done booting!
5360                SystemProperties.set("sys.boot_completed", "1");
5361                SystemProperties.set("dev.bootcomplete", "1");
5362                for (int i=0; i<mStartedUsers.size(); i++) {
5363                    UserStartedState uss = mStartedUsers.valueAt(i);
5364                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5365                        uss.mState = UserStartedState.STATE_RUNNING;
5366                        final int userId = mStartedUsers.keyAt(i);
5367                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5368                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5369                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5370                        broadcastIntentLocked(null, null, intent, null,
5371                                new IIntentReceiver.Stub() {
5372                                    @Override
5373                                    public void performReceive(Intent intent, int resultCode,
5374                                            String data, Bundle extras, boolean ordered,
5375                                            boolean sticky, int sendingUser) {
5376                                        synchronized (ActivityManagerService.this) {
5377                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5378                                                    true, false);
5379                                        }
5380                                    }
5381                                },
5382                                0, null, null,
5383                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5384                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5385                                userId);
5386                    }
5387                }
5388                scheduleStartProfilesLocked();
5389            }
5390        }
5391    }
5392
5393    final void ensureBootCompleted() {
5394        boolean booting;
5395        boolean enableScreen;
5396        synchronized (this) {
5397            booting = mBooting;
5398            mBooting = false;
5399            enableScreen = !mBooted;
5400            mBooted = true;
5401        }
5402
5403        if (booting) {
5404            finishBooting();
5405        }
5406
5407        if (enableScreen) {
5408            enableScreenAfterBoot();
5409        }
5410    }
5411
5412    @Override
5413    public final void activityResumed(IBinder token) {
5414        final long origId = Binder.clearCallingIdentity();
5415        synchronized(this) {
5416            ActivityStack stack = ActivityRecord.getStackLocked(token);
5417            if (stack != null) {
5418                ActivityRecord.activityResumedLocked(token);
5419            }
5420        }
5421        Binder.restoreCallingIdentity(origId);
5422    }
5423
5424    @Override
5425    public final void activityPaused(IBinder token) {
5426        final long origId = Binder.clearCallingIdentity();
5427        synchronized(this) {
5428            ActivityStack stack = ActivityRecord.getStackLocked(token);
5429            if (stack != null) {
5430                stack.activityPausedLocked(token, false);
5431            }
5432        }
5433        Binder.restoreCallingIdentity(origId);
5434    }
5435
5436    @Override
5437    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5438            CharSequence description) {
5439        if (localLOGV) Slog.v(
5440            TAG, "Activity stopped: token=" + token);
5441
5442        // Refuse possible leaked file descriptors
5443        if (icicle != null && icicle.hasFileDescriptors()) {
5444            throw new IllegalArgumentException("File descriptors passed in Bundle");
5445        }
5446
5447        final long origId = Binder.clearCallingIdentity();
5448
5449        synchronized (this) {
5450            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5451            if (r != null) {
5452                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5453            }
5454        }
5455
5456        trimApplications();
5457
5458        Binder.restoreCallingIdentity(origId);
5459    }
5460
5461    @Override
5462    public final void activityDestroyed(IBinder token) {
5463        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5464        synchronized (this) {
5465            ActivityStack stack = ActivityRecord.getStackLocked(token);
5466            if (stack != null) {
5467                stack.activityDestroyedLocked(token);
5468            }
5469        }
5470    }
5471
5472    @Override
5473    public String getCallingPackage(IBinder token) {
5474        synchronized (this) {
5475            ActivityRecord r = getCallingRecordLocked(token);
5476            return r != null ? r.info.packageName : null;
5477        }
5478    }
5479
5480    @Override
5481    public ComponentName getCallingActivity(IBinder token) {
5482        synchronized (this) {
5483            ActivityRecord r = getCallingRecordLocked(token);
5484            return r != null ? r.intent.getComponent() : null;
5485        }
5486    }
5487
5488    private ActivityRecord getCallingRecordLocked(IBinder token) {
5489        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5490        if (r == null) {
5491            return null;
5492        }
5493        return r.resultTo;
5494    }
5495
5496    @Override
5497    public ComponentName getActivityClassForToken(IBinder token) {
5498        synchronized(this) {
5499            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5500            if (r == null) {
5501                return null;
5502            }
5503            return r.intent.getComponent();
5504        }
5505    }
5506
5507    @Override
5508    public String getPackageForToken(IBinder token) {
5509        synchronized(this) {
5510            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5511            if (r == null) {
5512                return null;
5513            }
5514            return r.packageName;
5515        }
5516    }
5517
5518    @Override
5519    public IIntentSender getIntentSender(int type,
5520            String packageName, IBinder token, String resultWho,
5521            int requestCode, Intent[] intents, String[] resolvedTypes,
5522            int flags, Bundle options, int userId) {
5523        enforceNotIsolatedCaller("getIntentSender");
5524        // Refuse possible leaked file descriptors
5525        if (intents != null) {
5526            if (intents.length < 1) {
5527                throw new IllegalArgumentException("Intents array length must be >= 1");
5528            }
5529            for (int i=0; i<intents.length; i++) {
5530                Intent intent = intents[i];
5531                if (intent != null) {
5532                    if (intent.hasFileDescriptors()) {
5533                        throw new IllegalArgumentException("File descriptors passed in Intent");
5534                    }
5535                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5536                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5537                        throw new IllegalArgumentException(
5538                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5539                    }
5540                    intents[i] = new Intent(intent);
5541                }
5542            }
5543            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5544                throw new IllegalArgumentException(
5545                        "Intent array length does not match resolvedTypes length");
5546            }
5547        }
5548        if (options != null) {
5549            if (options.hasFileDescriptors()) {
5550                throw new IllegalArgumentException("File descriptors passed in options");
5551            }
5552        }
5553
5554        synchronized(this) {
5555            int callingUid = Binder.getCallingUid();
5556            int origUserId = userId;
5557            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5558                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5559                    "getIntentSender", null);
5560            if (origUserId == UserHandle.USER_CURRENT) {
5561                // We don't want to evaluate this until the pending intent is
5562                // actually executed.  However, we do want to always do the
5563                // security checking for it above.
5564                userId = UserHandle.USER_CURRENT;
5565            }
5566            try {
5567                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5568                    int uid = AppGlobals.getPackageManager()
5569                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5570                    if (!UserHandle.isSameApp(callingUid, uid)) {
5571                        String msg = "Permission Denial: getIntentSender() from pid="
5572                            + Binder.getCallingPid()
5573                            + ", uid=" + Binder.getCallingUid()
5574                            + ", (need uid=" + uid + ")"
5575                            + " is not allowed to send as package " + packageName;
5576                        Slog.w(TAG, msg);
5577                        throw new SecurityException(msg);
5578                    }
5579                }
5580
5581                return getIntentSenderLocked(type, packageName, callingUid, userId,
5582                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5583
5584            } catch (RemoteException e) {
5585                throw new SecurityException(e);
5586            }
5587        }
5588    }
5589
5590    IIntentSender getIntentSenderLocked(int type, String packageName,
5591            int callingUid, int userId, IBinder token, String resultWho,
5592            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5593            Bundle options) {
5594        if (DEBUG_MU)
5595            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5596        ActivityRecord activity = null;
5597        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5598            activity = ActivityRecord.isInStackLocked(token);
5599            if (activity == null) {
5600                return null;
5601            }
5602            if (activity.finishing) {
5603                return null;
5604            }
5605        }
5606
5607        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5608        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5609        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5610        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5611                |PendingIntent.FLAG_UPDATE_CURRENT);
5612
5613        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5614                type, packageName, activity, resultWho,
5615                requestCode, intents, resolvedTypes, flags, options, userId);
5616        WeakReference<PendingIntentRecord> ref;
5617        ref = mIntentSenderRecords.get(key);
5618        PendingIntentRecord rec = ref != null ? ref.get() : null;
5619        if (rec != null) {
5620            if (!cancelCurrent) {
5621                if (updateCurrent) {
5622                    if (rec.key.requestIntent != null) {
5623                        rec.key.requestIntent.replaceExtras(intents != null ?
5624                                intents[intents.length - 1] : null);
5625                    }
5626                    if (intents != null) {
5627                        intents[intents.length-1] = rec.key.requestIntent;
5628                        rec.key.allIntents = intents;
5629                        rec.key.allResolvedTypes = resolvedTypes;
5630                    } else {
5631                        rec.key.allIntents = null;
5632                        rec.key.allResolvedTypes = null;
5633                    }
5634                }
5635                return rec;
5636            }
5637            rec.canceled = true;
5638            mIntentSenderRecords.remove(key);
5639        }
5640        if (noCreate) {
5641            return rec;
5642        }
5643        rec = new PendingIntentRecord(this, key, callingUid);
5644        mIntentSenderRecords.put(key, rec.ref);
5645        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5646            if (activity.pendingResults == null) {
5647                activity.pendingResults
5648                        = new HashSet<WeakReference<PendingIntentRecord>>();
5649            }
5650            activity.pendingResults.add(rec.ref);
5651        }
5652        return rec;
5653    }
5654
5655    @Override
5656    public void cancelIntentSender(IIntentSender sender) {
5657        if (!(sender instanceof PendingIntentRecord)) {
5658            return;
5659        }
5660        synchronized(this) {
5661            PendingIntentRecord rec = (PendingIntentRecord)sender;
5662            try {
5663                int uid = AppGlobals.getPackageManager()
5664                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5665                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5666                    String msg = "Permission Denial: cancelIntentSender() from pid="
5667                        + Binder.getCallingPid()
5668                        + ", uid=" + Binder.getCallingUid()
5669                        + " is not allowed to cancel packges "
5670                        + rec.key.packageName;
5671                    Slog.w(TAG, msg);
5672                    throw new SecurityException(msg);
5673                }
5674            } catch (RemoteException e) {
5675                throw new SecurityException(e);
5676            }
5677            cancelIntentSenderLocked(rec, true);
5678        }
5679    }
5680
5681    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5682        rec.canceled = true;
5683        mIntentSenderRecords.remove(rec.key);
5684        if (cleanActivity && rec.key.activity != null) {
5685            rec.key.activity.pendingResults.remove(rec.ref);
5686        }
5687    }
5688
5689    @Override
5690    public String getPackageForIntentSender(IIntentSender pendingResult) {
5691        if (!(pendingResult instanceof PendingIntentRecord)) {
5692            return null;
5693        }
5694        try {
5695            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5696            return res.key.packageName;
5697        } catch (ClassCastException e) {
5698        }
5699        return null;
5700    }
5701
5702    @Override
5703    public int getUidForIntentSender(IIntentSender sender) {
5704        if (sender instanceof PendingIntentRecord) {
5705            try {
5706                PendingIntentRecord res = (PendingIntentRecord)sender;
5707                return res.uid;
5708            } catch (ClassCastException e) {
5709            }
5710        }
5711        return -1;
5712    }
5713
5714    @Override
5715    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5716        if (!(pendingResult instanceof PendingIntentRecord)) {
5717            return false;
5718        }
5719        try {
5720            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5721            if (res.key.allIntents == null) {
5722                return false;
5723            }
5724            for (int i=0; i<res.key.allIntents.length; i++) {
5725                Intent intent = res.key.allIntents[i];
5726                if (intent.getPackage() != null && intent.getComponent() != null) {
5727                    return false;
5728                }
5729            }
5730            return true;
5731        } catch (ClassCastException e) {
5732        }
5733        return false;
5734    }
5735
5736    @Override
5737    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5738        if (!(pendingResult instanceof PendingIntentRecord)) {
5739            return false;
5740        }
5741        try {
5742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5743            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5744                return true;
5745            }
5746            return false;
5747        } catch (ClassCastException e) {
5748        }
5749        return false;
5750    }
5751
5752    @Override
5753    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5754        if (!(pendingResult instanceof PendingIntentRecord)) {
5755            return null;
5756        }
5757        try {
5758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5759            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5760        } catch (ClassCastException e) {
5761        }
5762        return null;
5763    }
5764
5765    @Override
5766    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5767        if (!(pendingResult instanceof PendingIntentRecord)) {
5768            return null;
5769        }
5770        try {
5771            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5772            Intent intent = res.key.requestIntent;
5773            if (intent != null) {
5774                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5775                        || res.lastTagPrefix.equals(prefix))) {
5776                    return res.lastTag;
5777                }
5778                res.lastTagPrefix = prefix;
5779                StringBuilder sb = new StringBuilder(128);
5780                if (prefix != null) {
5781                    sb.append(prefix);
5782                }
5783                if (intent.getAction() != null) {
5784                    sb.append(intent.getAction());
5785                } else if (intent.getComponent() != null) {
5786                    intent.getComponent().appendShortString(sb);
5787                } else {
5788                    sb.append("?");
5789                }
5790                return res.lastTag = sb.toString();
5791            }
5792        } catch (ClassCastException e) {
5793        }
5794        return null;
5795    }
5796
5797    @Override
5798    public void setProcessLimit(int max) {
5799        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5800                "setProcessLimit()");
5801        synchronized (this) {
5802            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5803            mProcessLimitOverride = max;
5804        }
5805        trimApplications();
5806    }
5807
5808    @Override
5809    public int getProcessLimit() {
5810        synchronized (this) {
5811            return mProcessLimitOverride;
5812        }
5813    }
5814
5815    void foregroundTokenDied(ForegroundToken token) {
5816        synchronized (ActivityManagerService.this) {
5817            synchronized (mPidsSelfLocked) {
5818                ForegroundToken cur
5819                    = mForegroundProcesses.get(token.pid);
5820                if (cur != token) {
5821                    return;
5822                }
5823                mForegroundProcesses.remove(token.pid);
5824                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5825                if (pr == null) {
5826                    return;
5827                }
5828                pr.forcingToForeground = null;
5829                updateProcessForegroundLocked(pr, false, false);
5830            }
5831            updateOomAdjLocked();
5832        }
5833    }
5834
5835    @Override
5836    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5837        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5838                "setProcessForeground()");
5839        synchronized(this) {
5840            boolean changed = false;
5841
5842            synchronized (mPidsSelfLocked) {
5843                ProcessRecord pr = mPidsSelfLocked.get(pid);
5844                if (pr == null && isForeground) {
5845                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5846                    return;
5847                }
5848                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5849                if (oldToken != null) {
5850                    oldToken.token.unlinkToDeath(oldToken, 0);
5851                    mForegroundProcesses.remove(pid);
5852                    if (pr != null) {
5853                        pr.forcingToForeground = null;
5854                    }
5855                    changed = true;
5856                }
5857                if (isForeground && token != null) {
5858                    ForegroundToken newToken = new ForegroundToken() {
5859                        @Override
5860                        public void binderDied() {
5861                            foregroundTokenDied(this);
5862                        }
5863                    };
5864                    newToken.pid = pid;
5865                    newToken.token = token;
5866                    try {
5867                        token.linkToDeath(newToken, 0);
5868                        mForegroundProcesses.put(pid, newToken);
5869                        pr.forcingToForeground = token;
5870                        changed = true;
5871                    } catch (RemoteException e) {
5872                        // If the process died while doing this, we will later
5873                        // do the cleanup with the process death link.
5874                    }
5875                }
5876            }
5877
5878            if (changed) {
5879                updateOomAdjLocked();
5880            }
5881        }
5882    }
5883
5884    // =========================================================
5885    // PERMISSIONS
5886    // =========================================================
5887
5888    static class PermissionController extends IPermissionController.Stub {
5889        ActivityManagerService mActivityManagerService;
5890        PermissionController(ActivityManagerService activityManagerService) {
5891            mActivityManagerService = activityManagerService;
5892        }
5893
5894        @Override
5895        public boolean checkPermission(String permission, int pid, int uid) {
5896            return mActivityManagerService.checkPermission(permission, pid,
5897                    uid) == PackageManager.PERMISSION_GRANTED;
5898        }
5899    }
5900
5901    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5902        @Override
5903        public int checkComponentPermission(String permission, int pid, int uid,
5904                int owningUid, boolean exported) {
5905            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5906                    owningUid, exported);
5907        }
5908
5909        @Override
5910        public Object getAMSLock() {
5911            return ActivityManagerService.this;
5912        }
5913    }
5914
5915    /**
5916     * This can be called with or without the global lock held.
5917     */
5918    int checkComponentPermission(String permission, int pid, int uid,
5919            int owningUid, boolean exported) {
5920        // We might be performing an operation on behalf of an indirect binder
5921        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5922        // client identity accordingly before proceeding.
5923        Identity tlsIdentity = sCallerIdentity.get();
5924        if (tlsIdentity != null) {
5925            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5926                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5927            uid = tlsIdentity.uid;
5928            pid = tlsIdentity.pid;
5929        }
5930
5931        if (pid == MY_PID) {
5932            return PackageManager.PERMISSION_GRANTED;
5933        }
5934
5935        return ActivityManager.checkComponentPermission(permission, uid,
5936                owningUid, exported);
5937    }
5938
5939    /**
5940     * As the only public entry point for permissions checking, this method
5941     * can enforce the semantic that requesting a check on a null global
5942     * permission is automatically denied.  (Internally a null permission
5943     * string is used when calling {@link #checkComponentPermission} in cases
5944     * when only uid-based security is needed.)
5945     *
5946     * This can be called with or without the global lock held.
5947     */
5948    @Override
5949    public int checkPermission(String permission, int pid, int uid) {
5950        if (permission == null) {
5951            return PackageManager.PERMISSION_DENIED;
5952        }
5953        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5954    }
5955
5956    /**
5957     * Binder IPC calls go through the public entry point.
5958     * This can be called with or without the global lock held.
5959     */
5960    int checkCallingPermission(String permission) {
5961        return checkPermission(permission,
5962                Binder.getCallingPid(),
5963                UserHandle.getAppId(Binder.getCallingUid()));
5964    }
5965
5966    /**
5967     * This can be called with or without the global lock held.
5968     */
5969    void enforceCallingPermission(String permission, String func) {
5970        if (checkCallingPermission(permission)
5971                == PackageManager.PERMISSION_GRANTED) {
5972            return;
5973        }
5974
5975        String msg = "Permission Denial: " + func + " from pid="
5976                + Binder.getCallingPid()
5977                + ", uid=" + Binder.getCallingUid()
5978                + " requires " + permission;
5979        Slog.w(TAG, msg);
5980        throw new SecurityException(msg);
5981    }
5982
5983    /**
5984     * Determine if UID is holding permissions required to access {@link Uri} in
5985     * the given {@link ProviderInfo}. Final permission checking is always done
5986     * in {@link ContentProvider}.
5987     */
5988    private final boolean checkHoldingPermissionsLocked(
5989            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5990        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5991                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5992
5993        if (pi.applicationInfo.uid == uid) {
5994            return true;
5995        } else if (!pi.exported) {
5996            return false;
5997        }
5998
5999        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6000        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6001        try {
6002            // check if target holds top-level <provider> permissions
6003            if (!readMet && pi.readPermission != null
6004                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6005                readMet = true;
6006            }
6007            if (!writeMet && pi.writePermission != null
6008                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6009                writeMet = true;
6010            }
6011
6012            // track if unprotected read/write is allowed; any denied
6013            // <path-permission> below removes this ability
6014            boolean allowDefaultRead = pi.readPermission == null;
6015            boolean allowDefaultWrite = pi.writePermission == null;
6016
6017            // check if target holds any <path-permission> that match uri
6018            final PathPermission[] pps = pi.pathPermissions;
6019            if (pps != null) {
6020                final String path = uri.getPath();
6021                int i = pps.length;
6022                while (i > 0 && (!readMet || !writeMet)) {
6023                    i--;
6024                    PathPermission pp = pps[i];
6025                    if (pp.match(path)) {
6026                        if (!readMet) {
6027                            final String pprperm = pp.getReadPermission();
6028                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6029                                    + pprperm + " for " + pp.getPath()
6030                                    + ": match=" + pp.match(path)
6031                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6032                            if (pprperm != null) {
6033                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6034                                    readMet = true;
6035                                } else {
6036                                    allowDefaultRead = false;
6037                                }
6038                            }
6039                        }
6040                        if (!writeMet) {
6041                            final String ppwperm = pp.getWritePermission();
6042                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6043                                    + ppwperm + " for " + pp.getPath()
6044                                    + ": match=" + pp.match(path)
6045                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6046                            if (ppwperm != null) {
6047                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6048                                    writeMet = true;
6049                                } else {
6050                                    allowDefaultWrite = false;
6051                                }
6052                            }
6053                        }
6054                    }
6055                }
6056            }
6057
6058            // grant unprotected <provider> read/write, if not blocked by
6059            // <path-permission> above
6060            if (allowDefaultRead) readMet = true;
6061            if (allowDefaultWrite) writeMet = true;
6062
6063        } catch (RemoteException e) {
6064            return false;
6065        }
6066
6067        return readMet && writeMet;
6068    }
6069
6070    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6071        ProviderInfo pi = null;
6072        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6073        if (cpr != null) {
6074            pi = cpr.info;
6075        } else {
6076            try {
6077                pi = AppGlobals.getPackageManager().resolveContentProvider(
6078                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6079            } catch (RemoteException ex) {
6080            }
6081        }
6082        return pi;
6083    }
6084
6085    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6086        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6087        if (targetUris != null) {
6088            return targetUris.get(uri);
6089        }
6090        return null;
6091    }
6092
6093    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6094            String targetPkg, int targetUid, GrantUri uri) {
6095        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6096        if (targetUris == null) {
6097            targetUris = Maps.newArrayMap();
6098            mGrantedUriPermissions.put(targetUid, targetUris);
6099        }
6100
6101        UriPermission perm = targetUris.get(uri);
6102        if (perm == null) {
6103            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6104            targetUris.put(uri, perm);
6105        }
6106
6107        return perm;
6108    }
6109
6110    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6111        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6112        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6113                : UriPermission.STRENGTH_OWNED;
6114
6115        // Root gets to do everything.
6116        if (uid == 0) {
6117            return true;
6118        }
6119
6120        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6121        if (perms == null) return false;
6122
6123        // First look for exact match
6124        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6125        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6126            return true;
6127        }
6128
6129        // No exact match, look for prefixes
6130        final int N = perms.size();
6131        for (int i = 0; i < N; i++) {
6132            final UriPermission perm = perms.valueAt(i);
6133            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6134                    && perm.getStrength(modeFlags) >= minStrength) {
6135                return true;
6136            }
6137        }
6138
6139        return false;
6140    }
6141
6142    @Override
6143    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6144        enforceNotIsolatedCaller("checkUriPermission");
6145
6146        // Another redirected-binder-call permissions check as in
6147        // {@link checkComponentPermission}.
6148        Identity tlsIdentity = sCallerIdentity.get();
6149        if (tlsIdentity != null) {
6150            uid = tlsIdentity.uid;
6151            pid = tlsIdentity.pid;
6152        }
6153
6154        // Our own process gets to do everything.
6155        if (pid == MY_PID) {
6156            return PackageManager.PERMISSION_GRANTED;
6157        }
6158        synchronized (this) {
6159            return checkUriPermissionLocked(uri, uid, modeFlags)
6160                    ? PackageManager.PERMISSION_GRANTED
6161                    : PackageManager.PERMISSION_DENIED;
6162        }
6163    }
6164
6165    /**
6166     * Check if the targetPkg can be granted permission to access uri by
6167     * the callingUid using the given modeFlags.  Throws a security exception
6168     * if callingUid is not allowed to do this.  Returns the uid of the target
6169     * if the URI permission grant should be performed; returns -1 if it is not
6170     * needed (for example targetPkg already has permission to access the URI).
6171     * If you already know the uid of the target, you can supply it in
6172     * lastTargetUid else set that to -1.
6173     */
6174    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6175            Uri uri, final int modeFlags, int lastTargetUid) {
6176        if (!Intent.isAccessUriMode(modeFlags)) {
6177            return -1;
6178        }
6179
6180        if (targetPkg != null) {
6181            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6182                    "Checking grant " + targetPkg + " permission to " + uri);
6183        }
6184
6185        final IPackageManager pm = AppGlobals.getPackageManager();
6186
6187        // If this is not a content: uri, we can't do anything with it.
6188        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6189            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6190                    "Can't grant URI permission for non-content URI: " + uri);
6191            return -1;
6192        }
6193
6194        final String authority = uri.getAuthority();
6195        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6196        if (pi == null) {
6197            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6198            return -1;
6199        }
6200
6201        int targetUid = lastTargetUid;
6202        if (targetUid < 0 && targetPkg != null) {
6203            try {
6204                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6205                if (targetUid < 0) {
6206                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6207                            "Can't grant URI permission no uid for: " + targetPkg);
6208                    return -1;
6209                }
6210            } catch (RemoteException ex) {
6211                return -1;
6212            }
6213        }
6214
6215        if (targetUid >= 0) {
6216            // First...  does the target actually need this permission?
6217            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6218                // No need to grant the target this permission.
6219                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6220                        "Target " + targetPkg + " already has full permission to " + uri);
6221                return -1;
6222            }
6223        } else {
6224            // First...  there is no target package, so can anyone access it?
6225            boolean allowed = pi.exported;
6226            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6227                if (pi.readPermission != null) {
6228                    allowed = false;
6229                }
6230            }
6231            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6232                if (pi.writePermission != null) {
6233                    allowed = false;
6234                }
6235            }
6236            if (allowed) {
6237                return -1;
6238            }
6239        }
6240
6241        // Second...  is the provider allowing granting of URI permissions?
6242        if (!pi.grantUriPermissions) {
6243            throw new SecurityException("Provider " + pi.packageName
6244                    + "/" + pi.name
6245                    + " does not allow granting of Uri permissions (uri "
6246                    + uri + ")");
6247        }
6248        if (pi.uriPermissionPatterns != null) {
6249            final int N = pi.uriPermissionPatterns.length;
6250            boolean allowed = false;
6251            for (int i=0; i<N; i++) {
6252                if (pi.uriPermissionPatterns[i] != null
6253                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6254                    allowed = true;
6255                    break;
6256                }
6257            }
6258            if (!allowed) {
6259                throw new SecurityException("Provider " + pi.packageName
6260                        + "/" + pi.name
6261                        + " does not allow granting of permission to path of Uri "
6262                        + uri);
6263            }
6264        }
6265
6266        // Third...  does the caller itself have permission to access
6267        // this uri?
6268        if (callingUid != Process.myUid()) {
6269            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6270                // Require they hold a strong enough Uri permission
6271                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6272                    throw new SecurityException("Uid " + callingUid
6273                            + " does not have permission to uri " + uri);
6274                }
6275            }
6276        }
6277
6278        return targetUid;
6279    }
6280
6281    @Override
6282    public int checkGrantUriPermission(int callingUid, String targetPkg,
6283            Uri uri, final int modeFlags) {
6284        enforceNotIsolatedCaller("checkGrantUriPermission");
6285        synchronized(this) {
6286            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6287        }
6288    }
6289
6290    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6291            final int modeFlags, UriPermissionOwner owner) {
6292        if (!Intent.isAccessUriMode(modeFlags)) {
6293            return;
6294        }
6295
6296        // So here we are: the caller has the assumed permission
6297        // to the uri, and the target doesn't.  Let's now give this to
6298        // the target.
6299
6300        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6301                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6302
6303        final String authority = uri.getAuthority();
6304        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6305        if (pi == null) {
6306            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6307            return;
6308        }
6309
6310        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6311        final UriPermission perm = findOrCreateUriPermissionLocked(
6312                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6313        perm.grantModes(modeFlags, owner);
6314    }
6315
6316    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6317            final int modeFlags, UriPermissionOwner owner) {
6318        if (targetPkg == null) {
6319            throw new NullPointerException("targetPkg");
6320        }
6321
6322        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6323        if (targetUid < 0) {
6324            return;
6325        }
6326
6327        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6328    }
6329
6330    static class NeededUriGrants extends ArrayList<Uri> {
6331        final String targetPkg;
6332        final int targetUid;
6333        final int flags;
6334
6335        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6336            this.targetPkg = targetPkg;
6337            this.targetUid = targetUid;
6338            this.flags = flags;
6339        }
6340    }
6341
6342    /**
6343     * Like checkGrantUriPermissionLocked, but takes an Intent.
6344     */
6345    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6346            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6347        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6349                + " clip=" + (intent != null ? intent.getClipData() : null)
6350                + " from " + intent + "; flags=0x"
6351                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6352
6353        if (targetPkg == null) {
6354            throw new NullPointerException("targetPkg");
6355        }
6356
6357        if (intent == null) {
6358            return null;
6359        }
6360        Uri data = intent.getData();
6361        ClipData clip = intent.getClipData();
6362        if (data == null && clip == null) {
6363            return null;
6364        }
6365
6366        if (data != null) {
6367            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6368                mode, needed != null ? needed.targetUid : -1);
6369            if (targetUid > 0) {
6370                if (needed == null) {
6371                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6372                }
6373                needed.add(data);
6374            }
6375        }
6376        if (clip != null) {
6377            for (int i=0; i<clip.getItemCount(); i++) {
6378                Uri uri = clip.getItemAt(i).getUri();
6379                if (uri != null) {
6380                    int targetUid = -1;
6381                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6382                            mode, needed != null ? needed.targetUid : -1);
6383                    if (targetUid > 0) {
6384                        if (needed == null) {
6385                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6386                        }
6387                        needed.add(uri);
6388                    }
6389                } else {
6390                    Intent clipIntent = clip.getItemAt(i).getIntent();
6391                    if (clipIntent != null) {
6392                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6393                                callingUid, targetPkg, clipIntent, mode, needed);
6394                        if (newNeeded != null) {
6395                            needed = newNeeded;
6396                        }
6397                    }
6398                }
6399            }
6400        }
6401
6402        return needed;
6403    }
6404
6405    /**
6406     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6407     */
6408    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6409            UriPermissionOwner owner) {
6410        if (needed != null) {
6411            for (int i=0; i<needed.size(); i++) {
6412                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6413                        needed.get(i), needed.flags, owner);
6414            }
6415        }
6416    }
6417
6418    void grantUriPermissionFromIntentLocked(int callingUid,
6419            String targetPkg, Intent intent, UriPermissionOwner owner) {
6420        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6421                intent, intent != null ? intent.getFlags() : 0, null);
6422        if (needed == null) {
6423            return;
6424        }
6425
6426        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6427    }
6428
6429    @Override
6430    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6431            Uri uri, final int modeFlags) {
6432        enforceNotIsolatedCaller("grantUriPermission");
6433        synchronized(this) {
6434            final ProcessRecord r = getRecordForAppLocked(caller);
6435            if (r == null) {
6436                throw new SecurityException("Unable to find app for caller "
6437                        + caller
6438                        + " when granting permission to uri " + uri);
6439            }
6440            if (targetPkg == null) {
6441                throw new IllegalArgumentException("null target");
6442            }
6443            if (uri == null) {
6444                throw new IllegalArgumentException("null uri");
6445            }
6446
6447            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6448                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6449                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6450                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6451
6452            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6453        }
6454    }
6455
6456    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6457        if (perm.modeFlags == 0) {
6458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6459                    perm.targetUid);
6460            if (perms != null) {
6461                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6462                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6463
6464                perms.remove(perm.uri);
6465                if (perms.isEmpty()) {
6466                    mGrantedUriPermissions.remove(perm.targetUid);
6467                }
6468            }
6469        }
6470    }
6471
6472    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6473        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6474
6475        final IPackageManager pm = AppGlobals.getPackageManager();
6476        final String authority = uri.getAuthority();
6477        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6478        if (pi == null) {
6479            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6480            return;
6481        }
6482
6483        // Does the caller have this permission on the URI?
6484        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6485            // Right now, if you are not the original owner of the permission,
6486            // you are not allowed to revoke it.
6487            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6488                throw new SecurityException("Uid " + callingUid
6489                        + " does not have permission to uri " + uri);
6490            //}
6491        }
6492
6493        boolean persistChanged = false;
6494
6495        // Go through all of the permissions and remove any that match.
6496        int N = mGrantedUriPermissions.size();
6497        for (int i = 0; i < N; i++) {
6498            final int targetUid = mGrantedUriPermissions.keyAt(i);
6499            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6500
6501            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6502                final UriPermission perm = it.next();
6503                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6504                    if (DEBUG_URI_PERMISSION)
6505                        Slog.v(TAG,
6506                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6507                    persistChanged |= perm.revokeModes(
6508                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6509                    if (perm.modeFlags == 0) {
6510                        it.remove();
6511                    }
6512                }
6513            }
6514
6515            if (perms.isEmpty()) {
6516                mGrantedUriPermissions.remove(targetUid);
6517                N--;
6518                i--;
6519            }
6520        }
6521
6522        if (persistChanged) {
6523            schedulePersistUriGrants();
6524        }
6525    }
6526
6527    @Override
6528    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6529            final int modeFlags) {
6530        enforceNotIsolatedCaller("revokeUriPermission");
6531        synchronized(this) {
6532            final ProcessRecord r = getRecordForAppLocked(caller);
6533            if (r == null) {
6534                throw new SecurityException("Unable to find app for caller "
6535                        + caller
6536                        + " when revoking permission to uri " + uri);
6537            }
6538            if (uri == null) {
6539                Slog.w(TAG, "revokeUriPermission: null uri");
6540                return;
6541            }
6542
6543            if (!Intent.isAccessUriMode(modeFlags)) {
6544                return;
6545            }
6546
6547            final IPackageManager pm = AppGlobals.getPackageManager();
6548            final String authority = uri.getAuthority();
6549            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6550            if (pi == null) {
6551                Slog.w(TAG, "No content provider found for permission revoke: "
6552                        + uri.toSafeString());
6553                return;
6554            }
6555
6556            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6557        }
6558    }
6559
6560    /**
6561     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6562     * given package.
6563     *
6564     * @param packageName Package name to match, or {@code null} to apply to all
6565     *            packages.
6566     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6567     *            to all users.
6568     * @param persistable If persistable grants should be removed.
6569     */
6570    private void removeUriPermissionsForPackageLocked(
6571            String packageName, int userHandle, boolean persistable) {
6572        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6573            throw new IllegalArgumentException("Must narrow by either package or user");
6574        }
6575
6576        boolean persistChanged = false;
6577
6578        int N = mGrantedUriPermissions.size();
6579        for (int i = 0; i < N; i++) {
6580            final int targetUid = mGrantedUriPermissions.keyAt(i);
6581            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6582
6583            // Only inspect grants matching user
6584            if (userHandle == UserHandle.USER_ALL
6585                    || userHandle == UserHandle.getUserId(targetUid)) {
6586                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6587                    final UriPermission perm = it.next();
6588
6589                    // Only inspect grants matching package
6590                    if (packageName == null || perm.sourcePkg.equals(packageName)
6591                            || perm.targetPkg.equals(packageName)) {
6592                        persistChanged |= perm.revokeModes(
6593                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6594
6595                        // Only remove when no modes remain; any persisted grants
6596                        // will keep this alive.
6597                        if (perm.modeFlags == 0) {
6598                            it.remove();
6599                        }
6600                    }
6601                }
6602
6603                if (perms.isEmpty()) {
6604                    mGrantedUriPermissions.remove(targetUid);
6605                    N--;
6606                    i--;
6607                }
6608            }
6609        }
6610
6611        if (persistChanged) {
6612            schedulePersistUriGrants();
6613        }
6614    }
6615
6616    @Override
6617    public IBinder newUriPermissionOwner(String name) {
6618        enforceNotIsolatedCaller("newUriPermissionOwner");
6619        synchronized(this) {
6620            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6621            return owner.getExternalTokenLocked();
6622        }
6623    }
6624
6625    @Override
6626    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6627            Uri uri, final int modeFlags) {
6628        synchronized(this) {
6629            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6630            if (owner == null) {
6631                throw new IllegalArgumentException("Unknown owner: " + token);
6632            }
6633            if (fromUid != Binder.getCallingUid()) {
6634                if (Binder.getCallingUid() != Process.myUid()) {
6635                    // Only system code can grant URI permissions on behalf
6636                    // of other users.
6637                    throw new SecurityException("nice try");
6638                }
6639            }
6640            if (targetPkg == null) {
6641                throw new IllegalArgumentException("null target");
6642            }
6643            if (uri == null) {
6644                throw new IllegalArgumentException("null uri");
6645            }
6646
6647            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6648        }
6649    }
6650
6651    @Override
6652    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6653        synchronized(this) {
6654            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6655            if (owner == null) {
6656                throw new IllegalArgumentException("Unknown owner: " + token);
6657            }
6658
6659            if (uri == null) {
6660                owner.removeUriPermissionsLocked(mode);
6661            } else {
6662                owner.removeUriPermissionLocked(uri, mode);
6663            }
6664        }
6665    }
6666
6667    private void schedulePersistUriGrants() {
6668        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6669            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6670                    10 * DateUtils.SECOND_IN_MILLIS);
6671        }
6672    }
6673
6674    private void writeGrantedUriPermissions() {
6675        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6676
6677        // Snapshot permissions so we can persist without lock
6678        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6679        synchronized (this) {
6680            final int size = mGrantedUriPermissions.size();
6681            for (int i = 0; i < size; i++) {
6682                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6683                for (UriPermission perm : perms.values()) {
6684                    if (perm.persistedModeFlags != 0) {
6685                        persist.add(perm.snapshot());
6686                    }
6687                }
6688            }
6689        }
6690
6691        FileOutputStream fos = null;
6692        try {
6693            fos = mGrantFile.startWrite();
6694
6695            XmlSerializer out = new FastXmlSerializer();
6696            out.setOutput(fos, "utf-8");
6697            out.startDocument(null, true);
6698            out.startTag(null, TAG_URI_GRANTS);
6699            for (UriPermission.Snapshot perm : persist) {
6700                out.startTag(null, TAG_URI_GRANT);
6701                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6702                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6703                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6704                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6705                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6706                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6707                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6708                out.endTag(null, TAG_URI_GRANT);
6709            }
6710            out.endTag(null, TAG_URI_GRANTS);
6711            out.endDocument();
6712
6713            mGrantFile.finishWrite(fos);
6714        } catch (IOException e) {
6715            if (fos != null) {
6716                mGrantFile.failWrite(fos);
6717            }
6718        }
6719    }
6720
6721    private void readGrantedUriPermissionsLocked() {
6722        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6723
6724        final long now = System.currentTimeMillis();
6725
6726        FileInputStream fis = null;
6727        try {
6728            fis = mGrantFile.openRead();
6729            final XmlPullParser in = Xml.newPullParser();
6730            in.setInput(fis, null);
6731
6732            int type;
6733            while ((type = in.next()) != END_DOCUMENT) {
6734                final String tag = in.getName();
6735                if (type == START_TAG) {
6736                    if (TAG_URI_GRANT.equals(tag)) {
6737                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6738                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6739                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6740                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6741                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6742                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6743                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6744
6745                        // Sanity check that provider still belongs to source package
6746                        final ProviderInfo pi = getProviderInfoLocked(
6747                                uri.getAuthority(), userHandle);
6748                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6749                            int targetUid = -1;
6750                            try {
6751                                targetUid = AppGlobals.getPackageManager()
6752                                        .getPackageUid(targetPkg, userHandle);
6753                            } catch (RemoteException e) {
6754                            }
6755                            if (targetUid != -1) {
6756                                final UriPermission perm = findOrCreateUriPermissionLocked(
6757                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6758                                perm.initPersistedModes(modeFlags, createdTime);
6759                            }
6760                        } else {
6761                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6762                                    + " but instead found " + pi);
6763                        }
6764                    }
6765                }
6766            }
6767        } catch (FileNotFoundException e) {
6768            // Missing grants is okay
6769        } catch (IOException e) {
6770            Log.wtf(TAG, "Failed reading Uri grants", e);
6771        } catch (XmlPullParserException e) {
6772            Log.wtf(TAG, "Failed reading Uri grants", e);
6773        } finally {
6774            IoUtils.closeQuietly(fis);
6775        }
6776    }
6777
6778    @Override
6779    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6780        enforceNotIsolatedCaller("takePersistableUriPermission");
6781
6782        Preconditions.checkFlagsArgument(modeFlags,
6783                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6784
6785        synchronized (this) {
6786            final int callingUid = Binder.getCallingUid();
6787            boolean persistChanged = false;
6788
6789            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6790            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6791
6792            final boolean exactValid = (exactPerm != null)
6793                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6794            final boolean prefixValid = (prefixPerm != null)
6795                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6796
6797            if (!(exactValid || prefixValid)) {
6798                throw new SecurityException("No persistable permission grants found for UID "
6799                        + callingUid + " and Uri " + uri.toSafeString());
6800            }
6801
6802            if (exactValid) {
6803                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6804            }
6805            if (prefixValid) {
6806                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6807            }
6808
6809            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6810
6811            if (persistChanged) {
6812                schedulePersistUriGrants();
6813            }
6814        }
6815    }
6816
6817    @Override
6818    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6819        enforceNotIsolatedCaller("releasePersistableUriPermission");
6820
6821        Preconditions.checkFlagsArgument(modeFlags,
6822                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6823
6824        synchronized (this) {
6825            final int callingUid = Binder.getCallingUid();
6826            boolean persistChanged = false;
6827
6828            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6829            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6830            if (exactPerm == null && prefixPerm == null) {
6831                throw new SecurityException("No permission grants found for UID " + callingUid
6832                        + " and Uri " + uri.toSafeString());
6833            }
6834
6835            if (exactPerm != null) {
6836                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6837                removeUriPermissionIfNeededLocked(exactPerm);
6838            }
6839            if (prefixPerm != null) {
6840                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6841                removeUriPermissionIfNeededLocked(prefixPerm);
6842            }
6843
6844            if (persistChanged) {
6845                schedulePersistUriGrants();
6846            }
6847        }
6848    }
6849
6850    /**
6851     * Prune any older {@link UriPermission} for the given UID until outstanding
6852     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6853     *
6854     * @return if any mutations occured that require persisting.
6855     */
6856    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6858        if (perms == null) return false;
6859        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6860
6861        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6862        for (UriPermission perm : perms.values()) {
6863            if (perm.persistedModeFlags != 0) {
6864                persisted.add(perm);
6865            }
6866        }
6867
6868        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6869        if (trimCount <= 0) return false;
6870
6871        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6872        for (int i = 0; i < trimCount; i++) {
6873            final UriPermission perm = persisted.get(i);
6874
6875            if (DEBUG_URI_PERMISSION) {
6876                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6877            }
6878
6879            perm.releasePersistableModes(~0);
6880            removeUriPermissionIfNeededLocked(perm);
6881        }
6882
6883        return true;
6884    }
6885
6886    @Override
6887    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6888            String packageName, boolean incoming) {
6889        enforceNotIsolatedCaller("getPersistedUriPermissions");
6890        Preconditions.checkNotNull(packageName, "packageName");
6891
6892        final int callingUid = Binder.getCallingUid();
6893        final IPackageManager pm = AppGlobals.getPackageManager();
6894        try {
6895            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6896            if (packageUid != callingUid) {
6897                throw new SecurityException(
6898                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6899            }
6900        } catch (RemoteException e) {
6901            throw new SecurityException("Failed to verify package name ownership");
6902        }
6903
6904        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6905        synchronized (this) {
6906            if (incoming) {
6907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6908                        callingUid);
6909                if (perms == null) {
6910                    Slog.w(TAG, "No permission grants found for " + packageName);
6911                } else {
6912                    for (UriPermission perm : perms.values()) {
6913                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6914                            result.add(perm.buildPersistedPublicApiObject());
6915                        }
6916                    }
6917                }
6918            } else {
6919                final int size = mGrantedUriPermissions.size();
6920                for (int i = 0; i < size; i++) {
6921                    final ArrayMap<GrantUri, UriPermission> perms =
6922                            mGrantedUriPermissions.valueAt(i);
6923                    for (UriPermission perm : perms.values()) {
6924                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6925                            result.add(perm.buildPersistedPublicApiObject());
6926                        }
6927                    }
6928                }
6929            }
6930        }
6931        return new ParceledListSlice<android.content.UriPermission>(result);
6932    }
6933
6934    @Override
6935    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6936        synchronized (this) {
6937            ProcessRecord app =
6938                who != null ? getRecordForAppLocked(who) : null;
6939            if (app == null) return;
6940
6941            Message msg = Message.obtain();
6942            msg.what = WAIT_FOR_DEBUGGER_MSG;
6943            msg.obj = app;
6944            msg.arg1 = waiting ? 1 : 0;
6945            mHandler.sendMessage(msg);
6946        }
6947    }
6948
6949    @Override
6950    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6951        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6952        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6953        outInfo.availMem = Process.getFreeMemory();
6954        outInfo.totalMem = Process.getTotalMemory();
6955        outInfo.threshold = homeAppMem;
6956        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6957        outInfo.hiddenAppThreshold = cachedAppMem;
6958        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6959                ProcessList.SERVICE_ADJ);
6960        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6961                ProcessList.VISIBLE_APP_ADJ);
6962        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6963                ProcessList.FOREGROUND_APP_ADJ);
6964    }
6965
6966    // =========================================================
6967    // TASK MANAGEMENT
6968    // =========================================================
6969
6970    @Override
6971    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6972        final int callingUid = Binder.getCallingUid();
6973        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6974
6975        synchronized(this) {
6976            if (localLOGV) Slog.v(
6977                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6978
6979            final boolean allowed = checkCallingPermission(
6980                    android.Manifest.permission.GET_TASKS)
6981                    == PackageManager.PERMISSION_GRANTED;
6982            if (!allowed) {
6983                Slog.w(TAG, "getTasks: caller " + callingUid
6984                        + " does not hold GET_TASKS; limiting output");
6985            }
6986
6987            // TODO: Improve with MRU list from all ActivityStacks.
6988            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6989        }
6990
6991        return list;
6992    }
6993
6994    TaskRecord getMostRecentTask() {
6995        return mRecentTasks.get(0);
6996    }
6997
6998    @Override
6999    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7000            int flags, int userId) {
7001        final int callingUid = Binder.getCallingUid();
7002        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7003                false, true, "getRecentTasks", null);
7004
7005        synchronized (this) {
7006            final boolean allowed = checkCallingPermission(
7007                    android.Manifest.permission.GET_TASKS)
7008                    == PackageManager.PERMISSION_GRANTED;
7009            if (!allowed) {
7010                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7011                        + " does not hold GET_TASKS; limiting output");
7012            }
7013            final boolean detailed = checkCallingPermission(
7014                    android.Manifest.permission.GET_DETAILED_TASKS)
7015                    == PackageManager.PERMISSION_GRANTED;
7016
7017            IPackageManager pm = AppGlobals.getPackageManager();
7018
7019            final int N = mRecentTasks.size();
7020            ArrayList<ActivityManager.RecentTaskInfo> res
7021                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7022                            maxNum < N ? maxNum : N);
7023
7024            final Set<Integer> includedUsers;
7025            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7026                includedUsers = getProfileIdsLocked(userId);
7027            } else {
7028                includedUsers = new HashSet<Integer>();
7029            }
7030            includedUsers.add(Integer.valueOf(userId));
7031            for (int i=0; i<N && maxNum > 0; i++) {
7032                TaskRecord tr = mRecentTasks.get(i);
7033                // Only add calling user or related users recent tasks
7034                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7035
7036                // Return the entry if desired by the caller.  We always return
7037                // the first entry, because callers always expect this to be the
7038                // foreground app.  We may filter others if the caller has
7039                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7040                // we should exclude the entry.
7041
7042                if (i == 0
7043                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7044                        || (tr.intent == null)
7045                        || ((tr.intent.getFlags()
7046                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7047                    if (!allowed) {
7048                        // If the caller doesn't have the GET_TASKS permission, then only
7049                        // allow them to see a small subset of tasks -- their own and home.
7050                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7051                            continue;
7052                        }
7053                    }
7054                    ActivityManager.RecentTaskInfo rti
7055                            = new ActivityManager.RecentTaskInfo();
7056                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7057                    rti.persistentId = tr.taskId;
7058                    rti.baseIntent = new Intent(
7059                            tr.intent != null ? tr.intent : tr.affinityIntent);
7060                    if (!detailed) {
7061                        rti.baseIntent.replaceExtras((Bundle)null);
7062                    }
7063                    rti.origActivity = tr.origActivity;
7064                    rti.description = tr.lastDescription;
7065                    rti.stackId = tr.stack.mStackId;
7066                    rti.userId = tr.userId;
7067
7068                    // Traverse upwards looking for any break between main task activities and
7069                    // utility activities.
7070                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7071                    int activityNdx;
7072                    final int numActivities = activities.size();
7073                    for (activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
7074                        final ActivityRecord r = activities.get(activityNdx);
7075                        if (r.intent != null &&
7076                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7077                                        != 0) {
7078                            break;
7079                        }
7080                    }
7081                    if (activityNdx > 0) {
7082                        // Traverse downwards starting below break looking for set label, icon.
7083                        // Note that if there are activities in the task but none of them set the
7084                        // recent activity values, then we do not fall back to the last set
7085                        // values in the TaskRecord.
7086                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7087                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7088                            final ActivityRecord r = activities.get(activityNdx);
7089                            if (r.activityValues != null) {
7090                                if (rti.activityValues.label == null) {
7091                                    rti.activityValues.label = r.activityValues.label;
7092                                    tr.lastActivityValues.label = r.activityValues.label;
7093                                }
7094                                if (rti.activityValues.icon == null) {
7095                                    rti.activityValues.icon = r.activityValues.icon;
7096                                    tr.lastActivityValues.icon = r.activityValues.icon;
7097                                }
7098                                if (rti.activityValues.colorPrimary == 0) {
7099                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7100                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7101                                }
7102                            }
7103                        }
7104                    } else {
7105                        // If there are no activity records in this task, then we use the last
7106                        // resolved values
7107                        rti.activityValues =
7108                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7109                    }
7110
7111                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7112                        // Check whether this activity is currently available.
7113                        try {
7114                            if (rti.origActivity != null) {
7115                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7116                                        == null) {
7117                                    continue;
7118                                }
7119                            } else if (rti.baseIntent != null) {
7120                                if (pm.queryIntentActivities(rti.baseIntent,
7121                                        null, 0, userId) == null) {
7122                                    continue;
7123                                }
7124                            }
7125                        } catch (RemoteException e) {
7126                            // Will never happen.
7127                        }
7128                    }
7129
7130                    res.add(rti);
7131                    maxNum--;
7132                }
7133            }
7134            return res;
7135        }
7136    }
7137
7138    private TaskRecord recentTaskForIdLocked(int id) {
7139        final int N = mRecentTasks.size();
7140            for (int i=0; i<N; i++) {
7141                TaskRecord tr = mRecentTasks.get(i);
7142                if (tr.taskId == id) {
7143                    return tr;
7144                }
7145            }
7146            return null;
7147    }
7148
7149    @Override
7150    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7151        synchronized (this) {
7152            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7153                    "getTaskThumbnails()");
7154            TaskRecord tr = recentTaskForIdLocked(id);
7155            if (tr != null) {
7156                return tr.getTaskThumbnailsLocked();
7157            }
7158        }
7159        return null;
7160    }
7161
7162    @Override
7163    public Bitmap getTaskTopThumbnail(int id) {
7164        synchronized (this) {
7165            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7166                    "getTaskTopThumbnail()");
7167            TaskRecord tr = recentTaskForIdLocked(id);
7168            if (tr != null) {
7169                return tr.getTaskTopThumbnailLocked();
7170            }
7171        }
7172        return null;
7173    }
7174
7175    @Override
7176    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7177        synchronized (this) {
7178            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7179            if (r != null) {
7180                r.activityValues = rav;
7181            }
7182        }
7183    }
7184
7185    @Override
7186    public boolean removeSubTask(int taskId, int subTaskIndex) {
7187        synchronized (this) {
7188            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7189                    "removeSubTask()");
7190            long ident = Binder.clearCallingIdentity();
7191            try {
7192                TaskRecord tr = recentTaskForIdLocked(taskId);
7193                if (tr != null) {
7194                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7195                }
7196                return false;
7197            } finally {
7198                Binder.restoreCallingIdentity(ident);
7199            }
7200        }
7201    }
7202
7203    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7204        if (!pr.killedByAm) {
7205            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7206            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7207                    pr.processName, pr.setAdj, reason);
7208            pr.killedByAm = true;
7209            Process.killProcessQuiet(pr.pid);
7210        }
7211    }
7212
7213    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7214        tr.disposeThumbnail();
7215        mRecentTasks.remove(tr);
7216        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7217        Intent baseIntent = new Intent(
7218                tr.intent != null ? tr.intent : tr.affinityIntent);
7219        ComponentName component = baseIntent.getComponent();
7220        if (component == null) {
7221            Slog.w(TAG, "Now component for base intent of task: " + tr);
7222            return;
7223        }
7224
7225        // Find any running services associated with this app.
7226        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7227
7228        if (killProcesses) {
7229            // Find any running processes associated with this app.
7230            final String pkg = component.getPackageName();
7231            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7232            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7233            for (int i=0; i<pmap.size(); i++) {
7234                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7235                for (int j=0; j<uids.size(); j++) {
7236                    ProcessRecord proc = uids.valueAt(j);
7237                    if (proc.userId != tr.userId) {
7238                        continue;
7239                    }
7240                    if (!proc.pkgList.containsKey(pkg)) {
7241                        continue;
7242                    }
7243                    procs.add(proc);
7244                }
7245            }
7246
7247            // Kill the running processes.
7248            for (int i=0; i<procs.size(); i++) {
7249                ProcessRecord pr = procs.get(i);
7250                if (pr == mHomeProcess) {
7251                    // Don't kill the home process along with tasks from the same package.
7252                    continue;
7253                }
7254                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7255                    killUnneededProcessLocked(pr, "remove task");
7256                } else {
7257                    pr.waitingToKill = "remove task";
7258                }
7259            }
7260        }
7261    }
7262
7263    /**
7264     * Removes the task with the specified task id.
7265     *
7266     * @param taskId Identifier of the task to be removed.
7267     * @param flags Additional operational flags.  May be 0 or
7268     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7269     * @return Returns true if the given task was found and removed.
7270     */
7271    private boolean removeTaskByIdLocked(int taskId, int flags) {
7272        TaskRecord tr = recentTaskForIdLocked(taskId);
7273        if (tr != null) {
7274            tr.removeTaskActivitiesLocked(-1, false);
7275            cleanUpRemovedTaskLocked(tr, flags);
7276            return true;
7277        }
7278        return false;
7279    }
7280
7281    @Override
7282    public boolean removeTask(int taskId, int flags) {
7283        synchronized (this) {
7284            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7285                    "removeTask()");
7286            long ident = Binder.clearCallingIdentity();
7287            try {
7288                return removeTaskByIdLocked(taskId, flags);
7289            } finally {
7290                Binder.restoreCallingIdentity(ident);
7291            }
7292        }
7293    }
7294
7295    /**
7296     * TODO: Add mController hook
7297     */
7298    @Override
7299    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7300        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7301                "moveTaskToFront()");
7302
7303        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7304        synchronized(this) {
7305            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7306                    Binder.getCallingUid(), "Task to front")) {
7307                ActivityOptions.abort(options);
7308                return;
7309            }
7310            final long origId = Binder.clearCallingIdentity();
7311            try {
7312                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7313                if (task == null) {
7314                    return;
7315                }
7316                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7317                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7318                    return;
7319                }
7320                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7321            } finally {
7322                Binder.restoreCallingIdentity(origId);
7323            }
7324            ActivityOptions.abort(options);
7325        }
7326    }
7327
7328    @Override
7329    public void moveTaskToBack(int taskId) {
7330        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7331                "moveTaskToBack()");
7332
7333        synchronized(this) {
7334            TaskRecord tr = recentTaskForIdLocked(taskId);
7335            if (tr != null) {
7336                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7337                ActivityStack stack = tr.stack;
7338                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7339                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7340                            Binder.getCallingUid(), "Task to back")) {
7341                        return;
7342                    }
7343                }
7344                final long origId = Binder.clearCallingIdentity();
7345                try {
7346                    stack.moveTaskToBackLocked(taskId, null);
7347                } finally {
7348                    Binder.restoreCallingIdentity(origId);
7349                }
7350            }
7351        }
7352    }
7353
7354    /**
7355     * Moves an activity, and all of the other activities within the same task, to the bottom
7356     * of the history stack.  The activity's order within the task is unchanged.
7357     *
7358     * @param token A reference to the activity we wish to move
7359     * @param nonRoot If false then this only works if the activity is the root
7360     *                of a task; if true it will work for any activity in a task.
7361     * @return Returns true if the move completed, false if not.
7362     */
7363    @Override
7364    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7365        enforceNotIsolatedCaller("moveActivityTaskToBack");
7366        synchronized(this) {
7367            final long origId = Binder.clearCallingIdentity();
7368            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7369            if (taskId >= 0) {
7370                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7371            }
7372            Binder.restoreCallingIdentity(origId);
7373        }
7374        return false;
7375    }
7376
7377    @Override
7378    public void moveTaskBackwards(int task) {
7379        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7380                "moveTaskBackwards()");
7381
7382        synchronized(this) {
7383            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7384                    Binder.getCallingUid(), "Task backwards")) {
7385                return;
7386            }
7387            final long origId = Binder.clearCallingIdentity();
7388            moveTaskBackwardsLocked(task);
7389            Binder.restoreCallingIdentity(origId);
7390        }
7391    }
7392
7393    private final void moveTaskBackwardsLocked(int task) {
7394        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7395    }
7396
7397    @Override
7398    public IBinder getHomeActivityToken() throws RemoteException {
7399        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7400                "getHomeActivityToken()");
7401        synchronized (this) {
7402            return mStackSupervisor.getHomeActivityToken();
7403        }
7404    }
7405
7406    @Override
7407    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7408            IActivityContainerCallback callback) throws RemoteException {
7409        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7410                "createActivityContainer()");
7411        synchronized (this) {
7412            if (parentActivityToken == null) {
7413                throw new IllegalArgumentException("parent token must not be null");
7414            }
7415            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7416            if (r == null) {
7417                return null;
7418            }
7419            if (callback == null) {
7420                throw new IllegalArgumentException("callback must not be null");
7421            }
7422            return mStackSupervisor.createActivityContainer(r, callback);
7423        }
7424    }
7425
7426    @Override
7427    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7428        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7429                "deleteActivityContainer()");
7430        synchronized (this) {
7431            mStackSupervisor.deleteActivityContainer(container);
7432        }
7433    }
7434
7435    @Override
7436    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7437            throws RemoteException {
7438        synchronized (this) {
7439            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7440            if (stack != null) {
7441                return stack.mActivityContainer;
7442            }
7443            return null;
7444        }
7445    }
7446
7447    @Override
7448    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7449        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7450                "moveTaskToStack()");
7451        if (stackId == HOME_STACK_ID) {
7452            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7453                    new RuntimeException("here").fillInStackTrace());
7454        }
7455        synchronized (this) {
7456            long ident = Binder.clearCallingIdentity();
7457            try {
7458                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7459                        + stackId + " toTop=" + toTop);
7460                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7461            } finally {
7462                Binder.restoreCallingIdentity(ident);
7463            }
7464        }
7465    }
7466
7467    @Override
7468    public void resizeStack(int stackBoxId, Rect bounds) {
7469        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7470                "resizeStackBox()");
7471        long ident = Binder.clearCallingIdentity();
7472        try {
7473            mWindowManager.resizeStack(stackBoxId, bounds);
7474        } finally {
7475            Binder.restoreCallingIdentity(ident);
7476        }
7477    }
7478
7479    @Override
7480    public List<StackInfo> getAllStackInfos() {
7481        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7482                "getAllStackInfos()");
7483        long ident = Binder.clearCallingIdentity();
7484        try {
7485            synchronized (this) {
7486                return mStackSupervisor.getAllStackInfosLocked();
7487            }
7488        } finally {
7489            Binder.restoreCallingIdentity(ident);
7490        }
7491    }
7492
7493    @Override
7494    public StackInfo getStackInfo(int stackId) {
7495        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7496                "getStackInfo()");
7497        long ident = Binder.clearCallingIdentity();
7498        try {
7499            synchronized (this) {
7500                return mStackSupervisor.getStackInfoLocked(stackId);
7501            }
7502        } finally {
7503            Binder.restoreCallingIdentity(ident);
7504        }
7505    }
7506
7507    @Override
7508    public boolean isInHomeStack(int taskId) {
7509        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7510                "getStackInfo()");
7511        long ident = Binder.clearCallingIdentity();
7512        try {
7513            synchronized (this) {
7514                TaskRecord tr = recentTaskForIdLocked(taskId);
7515                if (tr != null) {
7516                    return tr.stack.isHomeStack();
7517                }
7518            }
7519        } finally {
7520            Binder.restoreCallingIdentity(ident);
7521        }
7522        return false;
7523    }
7524
7525    @Override
7526    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7527        synchronized(this) {
7528            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7529        }
7530    }
7531
7532    private boolean isLockTaskAuthorized(ComponentName name) {
7533//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7534//                "startLockTaskMode()");
7535//        DevicePolicyManager dpm = (DevicePolicyManager)
7536//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7537//        return dpm != null && dpm.isLockTaskPermitted(name);
7538        return true;
7539    }
7540
7541    private void startLockTaskMode(TaskRecord task) {
7542        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7543            return;
7544        }
7545        long ident = Binder.clearCallingIdentity();
7546        try {
7547            synchronized (this) {
7548                // Since we lost lock on task, make sure it is still there.
7549                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7550                if (task != null) {
7551                    mStackSupervisor.setLockTaskModeLocked(task);
7552                }
7553            }
7554        } finally {
7555            Binder.restoreCallingIdentity(ident);
7556        }
7557    }
7558
7559    @Override
7560    public void startLockTaskMode(int taskId) {
7561        long ident = Binder.clearCallingIdentity();
7562        try {
7563            final TaskRecord task;
7564            synchronized (this) {
7565                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7566            }
7567            if (task != null) {
7568                startLockTaskMode(task);
7569            }
7570        } finally {
7571            Binder.restoreCallingIdentity(ident);
7572        }
7573    }
7574
7575    @Override
7576    public void startLockTaskMode(IBinder token) {
7577        long ident = Binder.clearCallingIdentity();
7578        try {
7579            final TaskRecord task;
7580            synchronized (this) {
7581                final ActivityRecord r = ActivityRecord.forToken(token);
7582                if (r == null) {
7583                    return;
7584                }
7585                task = r.task;
7586            }
7587            if (task != null) {
7588                startLockTaskMode(task);
7589            }
7590        } finally {
7591            Binder.restoreCallingIdentity(ident);
7592        }
7593    }
7594
7595    @Override
7596    public void stopLockTaskMode() {
7597//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7598//                "stopLockTaskMode()");
7599        synchronized (this) {
7600            mStackSupervisor.setLockTaskModeLocked(null);
7601        }
7602    }
7603
7604    @Override
7605    public boolean isInLockTaskMode() {
7606        synchronized (this) {
7607            return mStackSupervisor.isInLockTaskMode();
7608        }
7609    }
7610
7611    // =========================================================
7612    // CONTENT PROVIDERS
7613    // =========================================================
7614
7615    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7616        List<ProviderInfo> providers = null;
7617        try {
7618            providers = AppGlobals.getPackageManager().
7619                queryContentProviders(app.processName, app.uid,
7620                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7621        } catch (RemoteException ex) {
7622        }
7623        if (DEBUG_MU)
7624            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7625        int userId = app.userId;
7626        if (providers != null) {
7627            int N = providers.size();
7628            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7629            for (int i=0; i<N; i++) {
7630                ProviderInfo cpi =
7631                    (ProviderInfo)providers.get(i);
7632                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7633                        cpi.name, cpi.flags);
7634                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7635                    // This is a singleton provider, but a user besides the
7636                    // default user is asking to initialize a process it runs
7637                    // in...  well, no, it doesn't actually run in this process,
7638                    // it runs in the process of the default user.  Get rid of it.
7639                    providers.remove(i);
7640                    N--;
7641                    i--;
7642                    continue;
7643                }
7644
7645                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7646                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7647                if (cpr == null) {
7648                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7649                    mProviderMap.putProviderByClass(comp, cpr);
7650                }
7651                if (DEBUG_MU)
7652                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7653                app.pubProviders.put(cpi.name, cpr);
7654                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7655                    // Don't add this if it is a platform component that is marked
7656                    // to run in multiple processes, because this is actually
7657                    // part of the framework so doesn't make sense to track as a
7658                    // separate apk in the process.
7659                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7660                }
7661                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7662            }
7663        }
7664        return providers;
7665    }
7666
7667    /**
7668     * Check if {@link ProcessRecord} has a possible chance at accessing the
7669     * given {@link ProviderInfo}. Final permission checking is always done
7670     * in {@link ContentProvider}.
7671     */
7672    private final String checkContentProviderPermissionLocked(
7673            ProviderInfo cpi, ProcessRecord r) {
7674        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7675        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7676        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7677                cpi.applicationInfo.uid, cpi.exported)
7678                == PackageManager.PERMISSION_GRANTED) {
7679            return null;
7680        }
7681        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7682                cpi.applicationInfo.uid, cpi.exported)
7683                == PackageManager.PERMISSION_GRANTED) {
7684            return null;
7685        }
7686
7687        PathPermission[] pps = cpi.pathPermissions;
7688        if (pps != null) {
7689            int i = pps.length;
7690            while (i > 0) {
7691                i--;
7692                PathPermission pp = pps[i];
7693                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7694                        cpi.applicationInfo.uid, cpi.exported)
7695                        == PackageManager.PERMISSION_GRANTED) {
7696                    return null;
7697                }
7698                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7699                        cpi.applicationInfo.uid, cpi.exported)
7700                        == PackageManager.PERMISSION_GRANTED) {
7701                    return null;
7702                }
7703            }
7704        }
7705
7706        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7707        if (perms != null) {
7708            for (GrantUri uri : perms.keySet()) {
7709                if (uri.uri.getAuthority().equals(cpi.authority)) {
7710                    return null;
7711                }
7712            }
7713        }
7714
7715        String msg;
7716        if (!cpi.exported) {
7717            msg = "Permission Denial: opening provider " + cpi.name
7718                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7719                    + ", uid=" + callingUid + ") that is not exported from uid "
7720                    + cpi.applicationInfo.uid;
7721        } else {
7722            msg = "Permission Denial: opening provider " + cpi.name
7723                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7724                    + ", uid=" + callingUid + ") requires "
7725                    + cpi.readPermission + " or " + cpi.writePermission;
7726        }
7727        Slog.w(TAG, msg);
7728        return msg;
7729    }
7730
7731    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7732            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7733        if (r != null) {
7734            for (int i=0; i<r.conProviders.size(); i++) {
7735                ContentProviderConnection conn = r.conProviders.get(i);
7736                if (conn.provider == cpr) {
7737                    if (DEBUG_PROVIDER) Slog.v(TAG,
7738                            "Adding provider requested by "
7739                            + r.processName + " from process "
7740                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7741                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7742                    if (stable) {
7743                        conn.stableCount++;
7744                        conn.numStableIncs++;
7745                    } else {
7746                        conn.unstableCount++;
7747                        conn.numUnstableIncs++;
7748                    }
7749                    return conn;
7750                }
7751            }
7752            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7753            if (stable) {
7754                conn.stableCount = 1;
7755                conn.numStableIncs = 1;
7756            } else {
7757                conn.unstableCount = 1;
7758                conn.numUnstableIncs = 1;
7759            }
7760            cpr.connections.add(conn);
7761            r.conProviders.add(conn);
7762            return conn;
7763        }
7764        cpr.addExternalProcessHandleLocked(externalProcessToken);
7765        return null;
7766    }
7767
7768    boolean decProviderCountLocked(ContentProviderConnection conn,
7769            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7770        if (conn != null) {
7771            cpr = conn.provider;
7772            if (DEBUG_PROVIDER) Slog.v(TAG,
7773                    "Removing provider requested by "
7774                    + conn.client.processName + " from process "
7775                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7776                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7777            if (stable) {
7778                conn.stableCount--;
7779            } else {
7780                conn.unstableCount--;
7781            }
7782            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7783                cpr.connections.remove(conn);
7784                conn.client.conProviders.remove(conn);
7785                return true;
7786            }
7787            return false;
7788        }
7789        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7790        return false;
7791    }
7792
7793    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7794            String name, IBinder token, boolean stable, int userId) {
7795        ContentProviderRecord cpr;
7796        ContentProviderConnection conn = null;
7797        ProviderInfo cpi = null;
7798
7799        synchronized(this) {
7800            ProcessRecord r = null;
7801            if (caller != null) {
7802                r = getRecordForAppLocked(caller);
7803                if (r == null) {
7804                    throw new SecurityException(
7805                            "Unable to find app for caller " + caller
7806                          + " (pid=" + Binder.getCallingPid()
7807                          + ") when getting content provider " + name);
7808                }
7809            }
7810
7811            // First check if this content provider has been published...
7812            cpr = mProviderMap.getProviderByName(name, userId);
7813            boolean providerRunning = cpr != null;
7814            if (providerRunning) {
7815                cpi = cpr.info;
7816                String msg;
7817                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7818                    throw new SecurityException(msg);
7819                }
7820
7821                if (r != null && cpr.canRunHere(r)) {
7822                    // This provider has been published or is in the process
7823                    // of being published...  but it is also allowed to run
7824                    // in the caller's process, so don't make a connection
7825                    // and just let the caller instantiate its own instance.
7826                    ContentProviderHolder holder = cpr.newHolder(null);
7827                    // don't give caller the provider object, it needs
7828                    // to make its own.
7829                    holder.provider = null;
7830                    return holder;
7831                }
7832
7833                final long origId = Binder.clearCallingIdentity();
7834
7835                // In this case the provider instance already exists, so we can
7836                // return it right away.
7837                conn = incProviderCountLocked(r, cpr, token, stable);
7838                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7839                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7840                        // If this is a perceptible app accessing the provider,
7841                        // make sure to count it as being accessed and thus
7842                        // back up on the LRU list.  This is good because
7843                        // content providers are often expensive to start.
7844                        updateLruProcessLocked(cpr.proc, false, null);
7845                    }
7846                }
7847
7848                if (cpr.proc != null) {
7849                    if (false) {
7850                        if (cpr.name.flattenToShortString().equals(
7851                                "com.android.providers.calendar/.CalendarProvider2")) {
7852                            Slog.v(TAG, "****************** KILLING "
7853                                + cpr.name.flattenToShortString());
7854                            Process.killProcess(cpr.proc.pid);
7855                        }
7856                    }
7857                    boolean success = updateOomAdjLocked(cpr.proc);
7858                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7859                    // NOTE: there is still a race here where a signal could be
7860                    // pending on the process even though we managed to update its
7861                    // adj level.  Not sure what to do about this, but at least
7862                    // the race is now smaller.
7863                    if (!success) {
7864                        // Uh oh...  it looks like the provider's process
7865                        // has been killed on us.  We need to wait for a new
7866                        // process to be started, and make sure its death
7867                        // doesn't kill our process.
7868                        Slog.i(TAG,
7869                                "Existing provider " + cpr.name.flattenToShortString()
7870                                + " is crashing; detaching " + r);
7871                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7872                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7873                        if (!lastRef) {
7874                            // This wasn't the last ref our process had on
7875                            // the provider...  we have now been killed, bail.
7876                            return null;
7877                        }
7878                        providerRunning = false;
7879                        conn = null;
7880                    }
7881                }
7882
7883                Binder.restoreCallingIdentity(origId);
7884            }
7885
7886            boolean singleton;
7887            if (!providerRunning) {
7888                try {
7889                    cpi = AppGlobals.getPackageManager().
7890                        resolveContentProvider(name,
7891                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7892                } catch (RemoteException ex) {
7893                }
7894                if (cpi == null) {
7895                    return null;
7896                }
7897                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7898                        cpi.name, cpi.flags);
7899                if (singleton) {
7900                    userId = 0;
7901                }
7902                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7903
7904                String msg;
7905                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7906                    throw new SecurityException(msg);
7907                }
7908
7909                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7910                        && !cpi.processName.equals("system")) {
7911                    // If this content provider does not run in the system
7912                    // process, and the system is not yet ready to run other
7913                    // processes, then fail fast instead of hanging.
7914                    throw new IllegalArgumentException(
7915                            "Attempt to launch content provider before system ready");
7916                }
7917
7918                // Make sure that the user who owns this provider is started.  If not,
7919                // we don't want to allow it to run.
7920                if (mStartedUsers.get(userId) == null) {
7921                    Slog.w(TAG, "Unable to launch app "
7922                            + cpi.applicationInfo.packageName + "/"
7923                            + cpi.applicationInfo.uid + " for provider "
7924                            + name + ": user " + userId + " is stopped");
7925                    return null;
7926                }
7927
7928                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7929                cpr = mProviderMap.getProviderByClass(comp, userId);
7930                final boolean firstClass = cpr == null;
7931                if (firstClass) {
7932                    try {
7933                        ApplicationInfo ai =
7934                            AppGlobals.getPackageManager().
7935                                getApplicationInfo(
7936                                        cpi.applicationInfo.packageName,
7937                                        STOCK_PM_FLAGS, userId);
7938                        if (ai == null) {
7939                            Slog.w(TAG, "No package info for content provider "
7940                                    + cpi.name);
7941                            return null;
7942                        }
7943                        ai = getAppInfoForUser(ai, userId);
7944                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7945                    } catch (RemoteException ex) {
7946                        // pm is in same process, this will never happen.
7947                    }
7948                }
7949
7950                if (r != null && cpr.canRunHere(r)) {
7951                    // If this is a multiprocess provider, then just return its
7952                    // info and allow the caller to instantiate it.  Only do
7953                    // this if the provider is the same user as the caller's
7954                    // process, or can run as root (so can be in any process).
7955                    return cpr.newHolder(null);
7956                }
7957
7958                if (DEBUG_PROVIDER) {
7959                    RuntimeException e = new RuntimeException("here");
7960                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7961                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7962                }
7963
7964                // This is single process, and our app is now connecting to it.
7965                // See if we are already in the process of launching this
7966                // provider.
7967                final int N = mLaunchingProviders.size();
7968                int i;
7969                for (i=0; i<N; i++) {
7970                    if (mLaunchingProviders.get(i) == cpr) {
7971                        break;
7972                    }
7973                }
7974
7975                // If the provider is not already being launched, then get it
7976                // started.
7977                if (i >= N) {
7978                    final long origId = Binder.clearCallingIdentity();
7979
7980                    try {
7981                        // Content provider is now in use, its package can't be stopped.
7982                        try {
7983                            AppGlobals.getPackageManager().setPackageStoppedState(
7984                                    cpr.appInfo.packageName, false, userId);
7985                        } catch (RemoteException e) {
7986                        } catch (IllegalArgumentException e) {
7987                            Slog.w(TAG, "Failed trying to unstop package "
7988                                    + cpr.appInfo.packageName + ": " + e);
7989                        }
7990
7991                        // Use existing process if already started
7992                        ProcessRecord proc = getProcessRecordLocked(
7993                                cpi.processName, cpr.appInfo.uid, false);
7994                        if (proc != null && proc.thread != null) {
7995                            if (DEBUG_PROVIDER) {
7996                                Slog.d(TAG, "Installing in existing process " + proc);
7997                            }
7998                            proc.pubProviders.put(cpi.name, cpr);
7999                            try {
8000                                proc.thread.scheduleInstallProvider(cpi);
8001                            } catch (RemoteException e) {
8002                            }
8003                        } else {
8004                            proc = startProcessLocked(cpi.processName,
8005                                    cpr.appInfo, false, 0, "content provider",
8006                                    new ComponentName(cpi.applicationInfo.packageName,
8007                                            cpi.name), false, false, false);
8008                            if (proc == null) {
8009                                Slog.w(TAG, "Unable to launch app "
8010                                        + cpi.applicationInfo.packageName + "/"
8011                                        + cpi.applicationInfo.uid + " for provider "
8012                                        + name + ": process is bad");
8013                                return null;
8014                            }
8015                        }
8016                        cpr.launchingApp = proc;
8017                        mLaunchingProviders.add(cpr);
8018                    } finally {
8019                        Binder.restoreCallingIdentity(origId);
8020                    }
8021                }
8022
8023                // Make sure the provider is published (the same provider class
8024                // may be published under multiple names).
8025                if (firstClass) {
8026                    mProviderMap.putProviderByClass(comp, cpr);
8027                }
8028
8029                mProviderMap.putProviderByName(name, cpr);
8030                conn = incProviderCountLocked(r, cpr, token, stable);
8031                if (conn != null) {
8032                    conn.waiting = true;
8033                }
8034            }
8035        }
8036
8037        // Wait for the provider to be published...
8038        synchronized (cpr) {
8039            while (cpr.provider == null) {
8040                if (cpr.launchingApp == null) {
8041                    Slog.w(TAG, "Unable to launch app "
8042                            + cpi.applicationInfo.packageName + "/"
8043                            + cpi.applicationInfo.uid + " for provider "
8044                            + name + ": launching app became null");
8045                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8046                            UserHandle.getUserId(cpi.applicationInfo.uid),
8047                            cpi.applicationInfo.packageName,
8048                            cpi.applicationInfo.uid, name);
8049                    return null;
8050                }
8051                try {
8052                    if (DEBUG_MU) {
8053                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8054                                + cpr.launchingApp);
8055                    }
8056                    if (conn != null) {
8057                        conn.waiting = true;
8058                    }
8059                    cpr.wait();
8060                } catch (InterruptedException ex) {
8061                } finally {
8062                    if (conn != null) {
8063                        conn.waiting = false;
8064                    }
8065                }
8066            }
8067        }
8068        return cpr != null ? cpr.newHolder(conn) : null;
8069    }
8070
8071    public final ContentProviderHolder getContentProvider(
8072            IApplicationThread caller, String name, int userId, boolean stable) {
8073        enforceNotIsolatedCaller("getContentProvider");
8074        if (caller == null) {
8075            String msg = "null IApplicationThread when getting content provider "
8076                    + name;
8077            Slog.w(TAG, msg);
8078            throw new SecurityException(msg);
8079        }
8080
8081        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8082                false, true, "getContentProvider", null);
8083        return getContentProviderImpl(caller, name, null, stable, userId);
8084    }
8085
8086    public ContentProviderHolder getContentProviderExternal(
8087            String name, int userId, IBinder token) {
8088        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8089            "Do not have permission in call getContentProviderExternal()");
8090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8091                false, true, "getContentProvider", null);
8092        return getContentProviderExternalUnchecked(name, token, userId);
8093    }
8094
8095    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8096            IBinder token, int userId) {
8097        return getContentProviderImpl(null, name, token, true, userId);
8098    }
8099
8100    /**
8101     * Drop a content provider from a ProcessRecord's bookkeeping
8102     */
8103    public void removeContentProvider(IBinder connection, boolean stable) {
8104        enforceNotIsolatedCaller("removeContentProvider");
8105        long ident = Binder.clearCallingIdentity();
8106        try {
8107            synchronized (this) {
8108                ContentProviderConnection conn;
8109                try {
8110                    conn = (ContentProviderConnection)connection;
8111                } catch (ClassCastException e) {
8112                    String msg ="removeContentProvider: " + connection
8113                            + " not a ContentProviderConnection";
8114                    Slog.w(TAG, msg);
8115                    throw new IllegalArgumentException(msg);
8116                }
8117                if (conn == null) {
8118                    throw new NullPointerException("connection is null");
8119                }
8120                if (decProviderCountLocked(conn, null, null, stable)) {
8121                    updateOomAdjLocked();
8122                }
8123            }
8124        } finally {
8125            Binder.restoreCallingIdentity(ident);
8126        }
8127    }
8128
8129    public void removeContentProviderExternal(String name, IBinder token) {
8130        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8131            "Do not have permission in call removeContentProviderExternal()");
8132        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8133    }
8134
8135    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8136        synchronized (this) {
8137            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8138            if(cpr == null) {
8139                //remove from mProvidersByClass
8140                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8141                return;
8142            }
8143
8144            //update content provider record entry info
8145            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8146            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8147            if (localCpr.hasExternalProcessHandles()) {
8148                if (localCpr.removeExternalProcessHandleLocked(token)) {
8149                    updateOomAdjLocked();
8150                } else {
8151                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8152                            + " with no external reference for token: "
8153                            + token + ".");
8154                }
8155            } else {
8156                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8157                        + " with no external references.");
8158            }
8159        }
8160    }
8161
8162    public final void publishContentProviders(IApplicationThread caller,
8163            List<ContentProviderHolder> providers) {
8164        if (providers == null) {
8165            return;
8166        }
8167
8168        enforceNotIsolatedCaller("publishContentProviders");
8169        synchronized (this) {
8170            final ProcessRecord r = getRecordForAppLocked(caller);
8171            if (DEBUG_MU)
8172                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8173            if (r == null) {
8174                throw new SecurityException(
8175                        "Unable to find app for caller " + caller
8176                      + " (pid=" + Binder.getCallingPid()
8177                      + ") when publishing content providers");
8178            }
8179
8180            final long origId = Binder.clearCallingIdentity();
8181
8182            final int N = providers.size();
8183            for (int i=0; i<N; i++) {
8184                ContentProviderHolder src = providers.get(i);
8185                if (src == null || src.info == null || src.provider == null) {
8186                    continue;
8187                }
8188                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8189                if (DEBUG_MU)
8190                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8191                if (dst != null) {
8192                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8193                    mProviderMap.putProviderByClass(comp, dst);
8194                    String names[] = dst.info.authority.split(";");
8195                    for (int j = 0; j < names.length; j++) {
8196                        mProviderMap.putProviderByName(names[j], dst);
8197                    }
8198
8199                    int NL = mLaunchingProviders.size();
8200                    int j;
8201                    for (j=0; j<NL; j++) {
8202                        if (mLaunchingProviders.get(j) == dst) {
8203                            mLaunchingProviders.remove(j);
8204                            j--;
8205                            NL--;
8206                        }
8207                    }
8208                    synchronized (dst) {
8209                        dst.provider = src.provider;
8210                        dst.proc = r;
8211                        dst.notifyAll();
8212                    }
8213                    updateOomAdjLocked(r);
8214                }
8215            }
8216
8217            Binder.restoreCallingIdentity(origId);
8218        }
8219    }
8220
8221    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8222        ContentProviderConnection conn;
8223        try {
8224            conn = (ContentProviderConnection)connection;
8225        } catch (ClassCastException e) {
8226            String msg ="refContentProvider: " + connection
8227                    + " not a ContentProviderConnection";
8228            Slog.w(TAG, msg);
8229            throw new IllegalArgumentException(msg);
8230        }
8231        if (conn == null) {
8232            throw new NullPointerException("connection is null");
8233        }
8234
8235        synchronized (this) {
8236            if (stable > 0) {
8237                conn.numStableIncs += stable;
8238            }
8239            stable = conn.stableCount + stable;
8240            if (stable < 0) {
8241                throw new IllegalStateException("stableCount < 0: " + stable);
8242            }
8243
8244            if (unstable > 0) {
8245                conn.numUnstableIncs += unstable;
8246            }
8247            unstable = conn.unstableCount + unstable;
8248            if (unstable < 0) {
8249                throw new IllegalStateException("unstableCount < 0: " + unstable);
8250            }
8251
8252            if ((stable+unstable) <= 0) {
8253                throw new IllegalStateException("ref counts can't go to zero here: stable="
8254                        + stable + " unstable=" + unstable);
8255            }
8256            conn.stableCount = stable;
8257            conn.unstableCount = unstable;
8258            return !conn.dead;
8259        }
8260    }
8261
8262    public void unstableProviderDied(IBinder connection) {
8263        ContentProviderConnection conn;
8264        try {
8265            conn = (ContentProviderConnection)connection;
8266        } catch (ClassCastException e) {
8267            String msg ="refContentProvider: " + connection
8268                    + " not a ContentProviderConnection";
8269            Slog.w(TAG, msg);
8270            throw new IllegalArgumentException(msg);
8271        }
8272        if (conn == null) {
8273            throw new NullPointerException("connection is null");
8274        }
8275
8276        // Safely retrieve the content provider associated with the connection.
8277        IContentProvider provider;
8278        synchronized (this) {
8279            provider = conn.provider.provider;
8280        }
8281
8282        if (provider == null) {
8283            // Um, yeah, we're way ahead of you.
8284            return;
8285        }
8286
8287        // Make sure the caller is being honest with us.
8288        if (provider.asBinder().pingBinder()) {
8289            // Er, no, still looks good to us.
8290            synchronized (this) {
8291                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8292                        + " says " + conn + " died, but we don't agree");
8293                return;
8294            }
8295        }
8296
8297        // Well look at that!  It's dead!
8298        synchronized (this) {
8299            if (conn.provider.provider != provider) {
8300                // But something changed...  good enough.
8301                return;
8302            }
8303
8304            ProcessRecord proc = conn.provider.proc;
8305            if (proc == null || proc.thread == null) {
8306                // Seems like the process is already cleaned up.
8307                return;
8308            }
8309
8310            // As far as we're concerned, this is just like receiving a
8311            // death notification...  just a bit prematurely.
8312            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8313                    + ") early provider death");
8314            final long ident = Binder.clearCallingIdentity();
8315            try {
8316                appDiedLocked(proc, proc.pid, proc.thread);
8317            } finally {
8318                Binder.restoreCallingIdentity(ident);
8319            }
8320        }
8321    }
8322
8323    @Override
8324    public void appNotRespondingViaProvider(IBinder connection) {
8325        enforceCallingPermission(
8326                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8327
8328        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8329        if (conn == null) {
8330            Slog.w(TAG, "ContentProviderConnection is null");
8331            return;
8332        }
8333
8334        final ProcessRecord host = conn.provider.proc;
8335        if (host == null) {
8336            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8337            return;
8338        }
8339
8340        final long token = Binder.clearCallingIdentity();
8341        try {
8342            appNotResponding(host, null, null, false, "ContentProvider not responding");
8343        } finally {
8344            Binder.restoreCallingIdentity(token);
8345        }
8346    }
8347
8348    public final void installSystemProviders() {
8349        List<ProviderInfo> providers;
8350        synchronized (this) {
8351            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8352            providers = generateApplicationProvidersLocked(app);
8353            if (providers != null) {
8354                for (int i=providers.size()-1; i>=0; i--) {
8355                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8356                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8357                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8358                                + ": not system .apk");
8359                        providers.remove(i);
8360                    }
8361                }
8362            }
8363        }
8364        if (providers != null) {
8365            mSystemThread.installSystemProviders(providers);
8366        }
8367
8368        mCoreSettingsObserver = new CoreSettingsObserver(this);
8369
8370        mUsageStatsService.monitorPackages();
8371    }
8372
8373    /**
8374     * Allows app to retrieve the MIME type of a URI without having permission
8375     * to access its content provider.
8376     *
8377     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8378     *
8379     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8380     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8381     */
8382    public String getProviderMimeType(Uri uri, int userId) {
8383        enforceNotIsolatedCaller("getProviderMimeType");
8384        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8385                userId, false, true, "getProviderMimeType", null);
8386        final String name = uri.getAuthority();
8387        final long ident = Binder.clearCallingIdentity();
8388        ContentProviderHolder holder = null;
8389
8390        try {
8391            holder = getContentProviderExternalUnchecked(name, null, userId);
8392            if (holder != null) {
8393                return holder.provider.getType(uri);
8394            }
8395        } catch (RemoteException e) {
8396            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8397            return null;
8398        } finally {
8399            if (holder != null) {
8400                removeContentProviderExternalUnchecked(name, null, userId);
8401            }
8402            Binder.restoreCallingIdentity(ident);
8403        }
8404
8405        return null;
8406    }
8407
8408    // =========================================================
8409    // GLOBAL MANAGEMENT
8410    // =========================================================
8411
8412    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8413            boolean isolated) {
8414        String proc = customProcess != null ? customProcess : info.processName;
8415        BatteryStatsImpl.Uid.Proc ps = null;
8416        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8417        int uid = info.uid;
8418        if (isolated) {
8419            int userId = UserHandle.getUserId(uid);
8420            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8421            while (true) {
8422                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8423                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8424                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8425                }
8426                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8427                mNextIsolatedProcessUid++;
8428                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8429                    // No process for this uid, use it.
8430                    break;
8431                }
8432                stepsLeft--;
8433                if (stepsLeft <= 0) {
8434                    return null;
8435                }
8436            }
8437        }
8438        return new ProcessRecord(stats, info, proc, uid);
8439    }
8440
8441    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8442        ProcessRecord app;
8443        if (!isolated) {
8444            app = getProcessRecordLocked(info.processName, info.uid, true);
8445        } else {
8446            app = null;
8447        }
8448
8449        if (app == null) {
8450            app = newProcessRecordLocked(info, null, isolated);
8451            mProcessNames.put(info.processName, app.uid, app);
8452            if (isolated) {
8453                mIsolatedProcesses.put(app.uid, app);
8454            }
8455            updateLruProcessLocked(app, false, null);
8456            updateOomAdjLocked();
8457        }
8458
8459        // This package really, really can not be stopped.
8460        try {
8461            AppGlobals.getPackageManager().setPackageStoppedState(
8462                    info.packageName, false, UserHandle.getUserId(app.uid));
8463        } catch (RemoteException e) {
8464        } catch (IllegalArgumentException e) {
8465            Slog.w(TAG, "Failed trying to unstop package "
8466                    + info.packageName + ": " + e);
8467        }
8468
8469        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8470                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8471            app.persistent = true;
8472            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8473        }
8474        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8475            mPersistentStartingProcesses.add(app);
8476            startProcessLocked(app, "added application", app.processName);
8477        }
8478
8479        return app;
8480    }
8481
8482    public void unhandledBack() {
8483        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8484                "unhandledBack()");
8485
8486        synchronized(this) {
8487            final long origId = Binder.clearCallingIdentity();
8488            try {
8489                getFocusedStack().unhandledBackLocked();
8490            } finally {
8491                Binder.restoreCallingIdentity(origId);
8492            }
8493        }
8494    }
8495
8496    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8497        enforceNotIsolatedCaller("openContentUri");
8498        final int userId = UserHandle.getCallingUserId();
8499        String name = uri.getAuthority();
8500        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8501        ParcelFileDescriptor pfd = null;
8502        if (cph != null) {
8503            // We record the binder invoker's uid in thread-local storage before
8504            // going to the content provider to open the file.  Later, in the code
8505            // that handles all permissions checks, we look for this uid and use
8506            // that rather than the Activity Manager's own uid.  The effect is that
8507            // we do the check against the caller's permissions even though it looks
8508            // to the content provider like the Activity Manager itself is making
8509            // the request.
8510            sCallerIdentity.set(new Identity(
8511                    Binder.getCallingPid(), Binder.getCallingUid()));
8512            try {
8513                pfd = cph.provider.openFile(null, uri, "r", null);
8514            } catch (FileNotFoundException e) {
8515                // do nothing; pfd will be returned null
8516            } finally {
8517                // Ensure that whatever happens, we clean up the identity state
8518                sCallerIdentity.remove();
8519            }
8520
8521            // We've got the fd now, so we're done with the provider.
8522            removeContentProviderExternalUnchecked(name, null, userId);
8523        } else {
8524            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8525        }
8526        return pfd;
8527    }
8528
8529    // Actually is sleeping or shutting down or whatever else in the future
8530    // is an inactive state.
8531    public boolean isSleepingOrShuttingDown() {
8532        return mSleeping || mShuttingDown;
8533    }
8534
8535    public boolean isSleeping() {
8536        return mSleeping;
8537    }
8538
8539    void goingToSleep() {
8540        synchronized(this) {
8541            mWentToSleep = true;
8542            updateEventDispatchingLocked();
8543            goToSleepIfNeededLocked();
8544        }
8545    }
8546
8547    void finishRunningVoiceLocked() {
8548        if (mRunningVoice) {
8549            mRunningVoice = false;
8550            goToSleepIfNeededLocked();
8551        }
8552    }
8553
8554    void goToSleepIfNeededLocked() {
8555        if (mWentToSleep && !mRunningVoice) {
8556            if (!mSleeping) {
8557                mSleeping = true;
8558                mStackSupervisor.goingToSleepLocked();
8559
8560                // Initialize the wake times of all processes.
8561                checkExcessivePowerUsageLocked(false);
8562                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8563                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8564                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8565            }
8566        }
8567    }
8568
8569    @Override
8570    public boolean shutdown(int timeout) {
8571        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8572                != PackageManager.PERMISSION_GRANTED) {
8573            throw new SecurityException("Requires permission "
8574                    + android.Manifest.permission.SHUTDOWN);
8575        }
8576
8577        boolean timedout = false;
8578
8579        synchronized(this) {
8580            mShuttingDown = true;
8581            updateEventDispatchingLocked();
8582            timedout = mStackSupervisor.shutdownLocked(timeout);
8583        }
8584
8585        mAppOpsService.shutdown();
8586        mUsageStatsService.shutdown();
8587        mBatteryStatsService.shutdown();
8588        synchronized (this) {
8589            mProcessStats.shutdownLocked();
8590        }
8591
8592        return timedout;
8593    }
8594
8595    public final void activitySlept(IBinder token) {
8596        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8597
8598        final long origId = Binder.clearCallingIdentity();
8599
8600        synchronized (this) {
8601            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8602            if (r != null) {
8603                mStackSupervisor.activitySleptLocked(r);
8604            }
8605        }
8606
8607        Binder.restoreCallingIdentity(origId);
8608    }
8609
8610    void logLockScreen(String msg) {
8611        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8612                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8613                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8614                mStackSupervisor.mDismissKeyguardOnNextActivity);
8615    }
8616
8617    private void comeOutOfSleepIfNeededLocked() {
8618        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8619            if (mSleeping) {
8620                mSleeping = false;
8621                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8622            }
8623        }
8624    }
8625
8626    void wakingUp() {
8627        synchronized(this) {
8628            mWentToSleep = false;
8629            updateEventDispatchingLocked();
8630            comeOutOfSleepIfNeededLocked();
8631        }
8632    }
8633
8634    void startRunningVoiceLocked() {
8635        if (!mRunningVoice) {
8636            mRunningVoice = true;
8637            comeOutOfSleepIfNeededLocked();
8638        }
8639    }
8640
8641    private void updateEventDispatchingLocked() {
8642        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8643    }
8644
8645    public void setLockScreenShown(boolean shown) {
8646        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8647                != PackageManager.PERMISSION_GRANTED) {
8648            throw new SecurityException("Requires permission "
8649                    + android.Manifest.permission.DEVICE_POWER);
8650        }
8651
8652        synchronized(this) {
8653            long ident = Binder.clearCallingIdentity();
8654            try {
8655                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8656                mLockScreenShown = shown;
8657                comeOutOfSleepIfNeededLocked();
8658            } finally {
8659                Binder.restoreCallingIdentity(ident);
8660            }
8661        }
8662    }
8663
8664    public void stopAppSwitches() {
8665        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8666                != PackageManager.PERMISSION_GRANTED) {
8667            throw new SecurityException("Requires permission "
8668                    + android.Manifest.permission.STOP_APP_SWITCHES);
8669        }
8670
8671        synchronized(this) {
8672            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8673                    + APP_SWITCH_DELAY_TIME;
8674            mDidAppSwitch = false;
8675            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8676            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8677            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8678        }
8679    }
8680
8681    public void resumeAppSwitches() {
8682        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8683                != PackageManager.PERMISSION_GRANTED) {
8684            throw new SecurityException("Requires permission "
8685                    + android.Manifest.permission.STOP_APP_SWITCHES);
8686        }
8687
8688        synchronized(this) {
8689            // Note that we don't execute any pending app switches... we will
8690            // let those wait until either the timeout, or the next start
8691            // activity request.
8692            mAppSwitchesAllowedTime = 0;
8693        }
8694    }
8695
8696    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8697            String name) {
8698        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8699            return true;
8700        }
8701
8702        final int perm = checkComponentPermission(
8703                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8704                callingUid, -1, true);
8705        if (perm == PackageManager.PERMISSION_GRANTED) {
8706            return true;
8707        }
8708
8709        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8710        return false;
8711    }
8712
8713    public void setDebugApp(String packageName, boolean waitForDebugger,
8714            boolean persistent) {
8715        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8716                "setDebugApp()");
8717
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            // Note that this is not really thread safe if there are multiple
8721            // callers into it at the same time, but that's not a situation we
8722            // care about.
8723            if (persistent) {
8724                final ContentResolver resolver = mContext.getContentResolver();
8725                Settings.Global.putString(
8726                    resolver, Settings.Global.DEBUG_APP,
8727                    packageName);
8728                Settings.Global.putInt(
8729                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8730                    waitForDebugger ? 1 : 0);
8731            }
8732
8733            synchronized (this) {
8734                if (!persistent) {
8735                    mOrigDebugApp = mDebugApp;
8736                    mOrigWaitForDebugger = mWaitForDebugger;
8737                }
8738                mDebugApp = packageName;
8739                mWaitForDebugger = waitForDebugger;
8740                mDebugTransient = !persistent;
8741                if (packageName != null) {
8742                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8743                            false, UserHandle.USER_ALL, "set debug app");
8744                }
8745            }
8746        } finally {
8747            Binder.restoreCallingIdentity(ident);
8748        }
8749    }
8750
8751    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8752        synchronized (this) {
8753            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8754            if (!isDebuggable) {
8755                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8756                    throw new SecurityException("Process not debuggable: " + app.packageName);
8757                }
8758            }
8759
8760            mOpenGlTraceApp = processName;
8761        }
8762    }
8763
8764    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8765            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8766        synchronized (this) {
8767            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8768            if (!isDebuggable) {
8769                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8770                    throw new SecurityException("Process not debuggable: " + app.packageName);
8771                }
8772            }
8773            mProfileApp = processName;
8774            mProfileFile = profileFile;
8775            if (mProfileFd != null) {
8776                try {
8777                    mProfileFd.close();
8778                } catch (IOException e) {
8779                }
8780                mProfileFd = null;
8781            }
8782            mProfileFd = profileFd;
8783            mProfileType = 0;
8784            mAutoStopProfiler = autoStopProfiler;
8785        }
8786    }
8787
8788    @Override
8789    public void setAlwaysFinish(boolean enabled) {
8790        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8791                "setAlwaysFinish()");
8792
8793        Settings.Global.putInt(
8794                mContext.getContentResolver(),
8795                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8796
8797        synchronized (this) {
8798            mAlwaysFinishActivities = enabled;
8799        }
8800    }
8801
8802    @Override
8803    public void setActivityController(IActivityController controller) {
8804        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8805                "setActivityController()");
8806        synchronized (this) {
8807            mController = controller;
8808            Watchdog.getInstance().setActivityController(controller);
8809        }
8810    }
8811
8812    @Override
8813    public void setUserIsMonkey(boolean userIsMonkey) {
8814        synchronized (this) {
8815            synchronized (mPidsSelfLocked) {
8816                final int callingPid = Binder.getCallingPid();
8817                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8818                if (precessRecord == null) {
8819                    throw new SecurityException("Unknown process: " + callingPid);
8820                }
8821                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8822                    throw new SecurityException("Only an instrumentation process "
8823                            + "with a UiAutomation can call setUserIsMonkey");
8824                }
8825            }
8826            mUserIsMonkey = userIsMonkey;
8827        }
8828    }
8829
8830    @Override
8831    public boolean isUserAMonkey() {
8832        synchronized (this) {
8833            // If there is a controller also implies the user is a monkey.
8834            return (mUserIsMonkey || mController != null);
8835        }
8836    }
8837
8838    public void requestBugReport() {
8839        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8840        SystemProperties.set("ctl.start", "bugreport");
8841    }
8842
8843    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8844        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8845    }
8846
8847    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8848        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8849            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8850        }
8851        return KEY_DISPATCHING_TIMEOUT;
8852    }
8853
8854    @Override
8855    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8856        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8857                != PackageManager.PERMISSION_GRANTED) {
8858            throw new SecurityException("Requires permission "
8859                    + android.Manifest.permission.FILTER_EVENTS);
8860        }
8861        ProcessRecord proc;
8862        long timeout;
8863        synchronized (this) {
8864            synchronized (mPidsSelfLocked) {
8865                proc = mPidsSelfLocked.get(pid);
8866            }
8867            timeout = getInputDispatchingTimeoutLocked(proc);
8868        }
8869
8870        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8871            return -1;
8872        }
8873
8874        return timeout;
8875    }
8876
8877    /**
8878     * Handle input dispatching timeouts.
8879     * Returns whether input dispatching should be aborted or not.
8880     */
8881    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8882            final ActivityRecord activity, final ActivityRecord parent,
8883            final boolean aboveSystem, String reason) {
8884        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8885                != PackageManager.PERMISSION_GRANTED) {
8886            throw new SecurityException("Requires permission "
8887                    + android.Manifest.permission.FILTER_EVENTS);
8888        }
8889
8890        final String annotation;
8891        if (reason == null) {
8892            annotation = "Input dispatching timed out";
8893        } else {
8894            annotation = "Input dispatching timed out (" + reason + ")";
8895        }
8896
8897        if (proc != null) {
8898            synchronized (this) {
8899                if (proc.debugging) {
8900                    return false;
8901                }
8902
8903                if (mDidDexOpt) {
8904                    // Give more time since we were dexopting.
8905                    mDidDexOpt = false;
8906                    return false;
8907                }
8908
8909                if (proc.instrumentationClass != null) {
8910                    Bundle info = new Bundle();
8911                    info.putString("shortMsg", "keyDispatchingTimedOut");
8912                    info.putString("longMsg", annotation);
8913                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8914                    return true;
8915                }
8916            }
8917            mHandler.post(new Runnable() {
8918                @Override
8919                public void run() {
8920                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8921                }
8922            });
8923        }
8924
8925        return true;
8926    }
8927
8928    public Bundle getAssistContextExtras(int requestType) {
8929        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8930                "getAssistContextExtras()");
8931        PendingAssistExtras pae;
8932        Bundle extras = new Bundle();
8933        synchronized (this) {
8934            ActivityRecord activity = getFocusedStack().mResumedActivity;
8935            if (activity == null) {
8936                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8937                return null;
8938            }
8939            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8940            if (activity.app == null || activity.app.thread == null) {
8941                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8942                return extras;
8943            }
8944            if (activity.app.pid == Binder.getCallingPid()) {
8945                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8946                return extras;
8947            }
8948            pae = new PendingAssistExtras(activity);
8949            try {
8950                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8951                        requestType);
8952                mPendingAssistExtras.add(pae);
8953                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8954            } catch (RemoteException e) {
8955                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8956                return extras;
8957            }
8958        }
8959        synchronized (pae) {
8960            while (!pae.haveResult) {
8961                try {
8962                    pae.wait();
8963                } catch (InterruptedException e) {
8964                }
8965            }
8966            if (pae.result != null) {
8967                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8968            }
8969        }
8970        synchronized (this) {
8971            mPendingAssistExtras.remove(pae);
8972            mHandler.removeCallbacks(pae);
8973        }
8974        return extras;
8975    }
8976
8977    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8978        PendingAssistExtras pae = (PendingAssistExtras)token;
8979        synchronized (pae) {
8980            pae.result = extras;
8981            pae.haveResult = true;
8982            pae.notifyAll();
8983        }
8984    }
8985
8986    public void registerProcessObserver(IProcessObserver observer) {
8987        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8988                "registerProcessObserver()");
8989        synchronized (this) {
8990            mProcessObservers.register(observer);
8991        }
8992    }
8993
8994    @Override
8995    public void unregisterProcessObserver(IProcessObserver observer) {
8996        synchronized (this) {
8997            mProcessObservers.unregister(observer);
8998        }
8999    }
9000
9001    @Override
9002    public boolean convertFromTranslucent(IBinder token) {
9003        final long origId = Binder.clearCallingIdentity();
9004        try {
9005            synchronized (this) {
9006                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9007                if (r == null) {
9008                    return false;
9009                }
9010                if (r.changeWindowTranslucency(true)) {
9011                    mWindowManager.setAppFullscreen(token, true);
9012                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9013                    return true;
9014                }
9015                return false;
9016            }
9017        } finally {
9018            Binder.restoreCallingIdentity(origId);
9019        }
9020    }
9021
9022    @Override
9023    public boolean convertToTranslucent(IBinder token) {
9024        final long origId = Binder.clearCallingIdentity();
9025        try {
9026            synchronized (this) {
9027                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9028                if (r == null) {
9029                    return false;
9030                }
9031                if (r.changeWindowTranslucency(false)) {
9032                    r.task.stack.convertToTranslucent(r);
9033                    mWindowManager.setAppFullscreen(token, false);
9034                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9035                    return true;
9036                }
9037                return false;
9038            }
9039        } finally {
9040            Binder.restoreCallingIdentity(origId);
9041        }
9042    }
9043
9044    @Override
9045    public void setImmersive(IBinder token, boolean immersive) {
9046        synchronized(this) {
9047            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9048            if (r == null) {
9049                throw new IllegalArgumentException();
9050            }
9051            r.immersive = immersive;
9052
9053            // update associated state if we're frontmost
9054            if (r == mFocusedActivity) {
9055                if (DEBUG_IMMERSIVE) {
9056                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9057                }
9058                applyUpdateLockStateLocked(r);
9059            }
9060        }
9061    }
9062
9063    @Override
9064    public boolean isImmersive(IBinder token) {
9065        synchronized (this) {
9066            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9067            if (r == null) {
9068                throw new IllegalArgumentException();
9069            }
9070            return r.immersive;
9071        }
9072    }
9073
9074    public boolean isTopActivityImmersive() {
9075        enforceNotIsolatedCaller("startActivity");
9076        synchronized (this) {
9077            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9078            return (r != null) ? r.immersive : false;
9079        }
9080    }
9081
9082    public final void enterSafeMode() {
9083        synchronized(this) {
9084            // It only makes sense to do this before the system is ready
9085            // and started launching other packages.
9086            if (!mSystemReady) {
9087                try {
9088                    AppGlobals.getPackageManager().enterSafeMode();
9089                } catch (RemoteException e) {
9090                }
9091            }
9092
9093            mSafeMode = true;
9094        }
9095    }
9096
9097    public final void showSafeModeOverlay() {
9098        View v = LayoutInflater.from(mContext).inflate(
9099                com.android.internal.R.layout.safe_mode, null);
9100        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9101        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9102        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9103        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9104        lp.gravity = Gravity.BOTTOM | Gravity.START;
9105        lp.format = v.getBackground().getOpacity();
9106        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9107                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9108        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9109        ((WindowManager)mContext.getSystemService(
9110                Context.WINDOW_SERVICE)).addView(v, lp);
9111    }
9112
9113    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9114        if (!(sender instanceof PendingIntentRecord)) {
9115            return;
9116        }
9117        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9118        synchronized (stats) {
9119            if (mBatteryStatsService.isOnBattery()) {
9120                mBatteryStatsService.enforceCallingPermission();
9121                PendingIntentRecord rec = (PendingIntentRecord)sender;
9122                int MY_UID = Binder.getCallingUid();
9123                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9124                BatteryStatsImpl.Uid.Pkg pkg =
9125                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9126                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9127                pkg.incWakeupsLocked();
9128            }
9129        }
9130    }
9131
9132    public boolean killPids(int[] pids, String pReason, boolean secure) {
9133        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9134            throw new SecurityException("killPids only available to the system");
9135        }
9136        String reason = (pReason == null) ? "Unknown" : pReason;
9137        // XXX Note: don't acquire main activity lock here, because the window
9138        // manager calls in with its locks held.
9139
9140        boolean killed = false;
9141        synchronized (mPidsSelfLocked) {
9142            int[] types = new int[pids.length];
9143            int worstType = 0;
9144            for (int i=0; i<pids.length; i++) {
9145                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9146                if (proc != null) {
9147                    int type = proc.setAdj;
9148                    types[i] = type;
9149                    if (type > worstType) {
9150                        worstType = type;
9151                    }
9152                }
9153            }
9154
9155            // If the worst oom_adj is somewhere in the cached proc LRU range,
9156            // then constrain it so we will kill all cached procs.
9157            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9158                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9159                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9160            }
9161
9162            // If this is not a secure call, don't let it kill processes that
9163            // are important.
9164            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9165                worstType = ProcessList.SERVICE_ADJ;
9166            }
9167
9168            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9169            for (int i=0; i<pids.length; i++) {
9170                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9171                if (proc == null) {
9172                    continue;
9173                }
9174                int adj = proc.setAdj;
9175                if (adj >= worstType && !proc.killedByAm) {
9176                    killUnneededProcessLocked(proc, reason);
9177                    killed = true;
9178                }
9179            }
9180        }
9181        return killed;
9182    }
9183
9184    @Override
9185    public void killUid(int uid, String reason) {
9186        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9187            throw new SecurityException("killUid only available to the system");
9188        }
9189        synchronized (this) {
9190            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9191                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9192                    reason != null ? reason : "kill uid");
9193        }
9194    }
9195
9196    @Override
9197    public boolean killProcessesBelowForeground(String reason) {
9198        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9199            throw new SecurityException("killProcessesBelowForeground() only available to system");
9200        }
9201
9202        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9203    }
9204
9205    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9206        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9207            throw new SecurityException("killProcessesBelowAdj() only available to system");
9208        }
9209
9210        boolean killed = false;
9211        synchronized (mPidsSelfLocked) {
9212            final int size = mPidsSelfLocked.size();
9213            for (int i = 0; i < size; i++) {
9214                final int pid = mPidsSelfLocked.keyAt(i);
9215                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9216                if (proc == null) continue;
9217
9218                final int adj = proc.setAdj;
9219                if (adj > belowAdj && !proc.killedByAm) {
9220                    killUnneededProcessLocked(proc, reason);
9221                    killed = true;
9222                }
9223            }
9224        }
9225        return killed;
9226    }
9227
9228    @Override
9229    public void hang(final IBinder who, boolean allowRestart) {
9230        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9231                != PackageManager.PERMISSION_GRANTED) {
9232            throw new SecurityException("Requires permission "
9233                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9234        }
9235
9236        final IBinder.DeathRecipient death = new DeathRecipient() {
9237            @Override
9238            public void binderDied() {
9239                synchronized (this) {
9240                    notifyAll();
9241                }
9242            }
9243        };
9244
9245        try {
9246            who.linkToDeath(death, 0);
9247        } catch (RemoteException e) {
9248            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9249            return;
9250        }
9251
9252        synchronized (this) {
9253            Watchdog.getInstance().setAllowRestart(allowRestart);
9254            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9255            synchronized (death) {
9256                while (who.isBinderAlive()) {
9257                    try {
9258                        death.wait();
9259                    } catch (InterruptedException e) {
9260                    }
9261                }
9262            }
9263            Watchdog.getInstance().setAllowRestart(true);
9264        }
9265    }
9266
9267    @Override
9268    public void restart() {
9269        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9270                != PackageManager.PERMISSION_GRANTED) {
9271            throw new SecurityException("Requires permission "
9272                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9273        }
9274
9275        Log.i(TAG, "Sending shutdown broadcast...");
9276
9277        BroadcastReceiver br = new BroadcastReceiver() {
9278            @Override public void onReceive(Context context, Intent intent) {
9279                // Now the broadcast is done, finish up the low-level shutdown.
9280                Log.i(TAG, "Shutting down activity manager...");
9281                shutdown(10000);
9282                Log.i(TAG, "Shutdown complete, restarting!");
9283                Process.killProcess(Process.myPid());
9284                System.exit(10);
9285            }
9286        };
9287
9288        // First send the high-level shut down broadcast.
9289        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9290        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9291        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9292        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9293        mContext.sendOrderedBroadcastAsUser(intent,
9294                UserHandle.ALL, null, br, mHandler, 0, null, null);
9295        */
9296        br.onReceive(mContext, intent);
9297    }
9298
9299    private long getLowRamTimeSinceIdle(long now) {
9300        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9301    }
9302
9303    @Override
9304    public void performIdleMaintenance() {
9305        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9306                != PackageManager.PERMISSION_GRANTED) {
9307            throw new SecurityException("Requires permission "
9308                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9309        }
9310
9311        synchronized (this) {
9312            final long now = SystemClock.uptimeMillis();
9313            final long timeSinceLastIdle = now - mLastIdleTime;
9314            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9315            mLastIdleTime = now;
9316            mLowRamTimeSinceLastIdle = 0;
9317            if (mLowRamStartTime != 0) {
9318                mLowRamStartTime = now;
9319            }
9320
9321            StringBuilder sb = new StringBuilder(128);
9322            sb.append("Idle maintenance over ");
9323            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9324            sb.append(" low RAM for ");
9325            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9326            Slog.i(TAG, sb.toString());
9327
9328            // If at least 1/3 of our time since the last idle period has been spent
9329            // with RAM low, then we want to kill processes.
9330            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9331
9332            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9333                ProcessRecord proc = mLruProcesses.get(i);
9334                if (proc.notCachedSinceIdle) {
9335                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9336                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9337                        if (doKilling && proc.initialIdlePss != 0
9338                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9339                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9340                                    + " from " + proc.initialIdlePss + ")");
9341                        }
9342                    }
9343                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9344                    proc.notCachedSinceIdle = true;
9345                    proc.initialIdlePss = 0;
9346                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9347                            isSleeping(), now);
9348                }
9349            }
9350
9351            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9352            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9353        }
9354    }
9355
9356    private void retrieveSettings() {
9357        final ContentResolver resolver = mContext.getContentResolver();
9358        String debugApp = Settings.Global.getString(
9359            resolver, Settings.Global.DEBUG_APP);
9360        boolean waitForDebugger = Settings.Global.getInt(
9361            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9362        boolean alwaysFinishActivities = Settings.Global.getInt(
9363            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9364        boolean forceRtl = Settings.Global.getInt(
9365                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9366        // Transfer any global setting for forcing RTL layout, into a System Property
9367        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9368
9369        Configuration configuration = new Configuration();
9370        Settings.System.getConfiguration(resolver, configuration);
9371        if (forceRtl) {
9372            // This will take care of setting the correct layout direction flags
9373            configuration.setLayoutDirection(configuration.locale);
9374        }
9375
9376        synchronized (this) {
9377            mDebugApp = mOrigDebugApp = debugApp;
9378            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9379            mAlwaysFinishActivities = alwaysFinishActivities;
9380            // This happens before any activities are started, so we can
9381            // change mConfiguration in-place.
9382            updateConfigurationLocked(configuration, null, false, true);
9383            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9384        }
9385    }
9386
9387    public boolean testIsSystemReady() {
9388        // no need to synchronize(this) just to read & return the value
9389        return mSystemReady;
9390    }
9391
9392    private static File getCalledPreBootReceiversFile() {
9393        File dataDir = Environment.getDataDirectory();
9394        File systemDir = new File(dataDir, "system");
9395        File fname = new File(systemDir, "called_pre_boots.dat");
9396        return fname;
9397    }
9398
9399    static final int LAST_DONE_VERSION = 10000;
9400
9401    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9402        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9403        File file = getCalledPreBootReceiversFile();
9404        FileInputStream fis = null;
9405        try {
9406            fis = new FileInputStream(file);
9407            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9408            int fvers = dis.readInt();
9409            if (fvers == LAST_DONE_VERSION) {
9410                String vers = dis.readUTF();
9411                String codename = dis.readUTF();
9412                String build = dis.readUTF();
9413                if (android.os.Build.VERSION.RELEASE.equals(vers)
9414                        && android.os.Build.VERSION.CODENAME.equals(codename)
9415                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9416                    int num = dis.readInt();
9417                    while (num > 0) {
9418                        num--;
9419                        String pkg = dis.readUTF();
9420                        String cls = dis.readUTF();
9421                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9422                    }
9423                }
9424            }
9425        } catch (FileNotFoundException e) {
9426        } catch (IOException e) {
9427            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9428        } finally {
9429            if (fis != null) {
9430                try {
9431                    fis.close();
9432                } catch (IOException e) {
9433                }
9434            }
9435        }
9436        return lastDoneReceivers;
9437    }
9438
9439    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9440        File file = getCalledPreBootReceiversFile();
9441        FileOutputStream fos = null;
9442        DataOutputStream dos = null;
9443        try {
9444            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9445            fos = new FileOutputStream(file);
9446            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9447            dos.writeInt(LAST_DONE_VERSION);
9448            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9449            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9450            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9451            dos.writeInt(list.size());
9452            for (int i=0; i<list.size(); i++) {
9453                dos.writeUTF(list.get(i).getPackageName());
9454                dos.writeUTF(list.get(i).getClassName());
9455            }
9456        } catch (IOException e) {
9457            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9458            file.delete();
9459        } finally {
9460            FileUtils.sync(fos);
9461            if (dos != null) {
9462                try {
9463                    dos.close();
9464                } catch (IOException e) {
9465                    // TODO Auto-generated catch block
9466                    e.printStackTrace();
9467                }
9468            }
9469        }
9470    }
9471
9472    public void systemReady(final Runnable goingCallback) {
9473        synchronized(this) {
9474            if (mSystemReady) {
9475                if (goingCallback != null) goingCallback.run();
9476                return;
9477            }
9478
9479            // Check to see if there are any update receivers to run.
9480            if (!mDidUpdate) {
9481                if (mWaitingUpdate) {
9482                    return;
9483                }
9484                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9485                List<ResolveInfo> ris = null;
9486                try {
9487                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9488                            intent, null, 0, 0);
9489                } catch (RemoteException e) {
9490                }
9491                if (ris != null) {
9492                    for (int i=ris.size()-1; i>=0; i--) {
9493                        if ((ris.get(i).activityInfo.applicationInfo.flags
9494                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9495                            ris.remove(i);
9496                        }
9497                    }
9498                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9499
9500                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9501
9502                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9503                    for (int i=0; i<ris.size(); i++) {
9504                        ActivityInfo ai = ris.get(i).activityInfo;
9505                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9506                        if (lastDoneReceivers.contains(comp)) {
9507                            // We already did the pre boot receiver for this app with the current
9508                            // platform version, so don't do it again...
9509                            ris.remove(i);
9510                            i--;
9511                            // ...however, do keep it as one that has been done, so we don't
9512                            // forget about it when rewriting the file of last done receivers.
9513                            doneReceivers.add(comp);
9514                        }
9515                    }
9516
9517                    final int[] users = getUsersLocked();
9518                    for (int i=0; i<ris.size(); i++) {
9519                        ActivityInfo ai = ris.get(i).activityInfo;
9520                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9521                        doneReceivers.add(comp);
9522                        intent.setComponent(comp);
9523                        for (int j=0; j<users.length; j++) {
9524                            IIntentReceiver finisher = null;
9525                            if (i == ris.size()-1 && j == users.length-1) {
9526                                finisher = new IIntentReceiver.Stub() {
9527                                    public void performReceive(Intent intent, int resultCode,
9528                                            String data, Bundle extras, boolean ordered,
9529                                            boolean sticky, int sendingUser) {
9530                                        // The raw IIntentReceiver interface is called
9531                                        // with the AM lock held, so redispatch to
9532                                        // execute our code without the lock.
9533                                        mHandler.post(new Runnable() {
9534                                            public void run() {
9535                                                synchronized (ActivityManagerService.this) {
9536                                                    mDidUpdate = true;
9537                                                }
9538                                                writeLastDonePreBootReceivers(doneReceivers);
9539                                                showBootMessage(mContext.getText(
9540                                                        R.string.android_upgrading_complete),
9541                                                        false);
9542                                                systemReady(goingCallback);
9543                                            }
9544                                        });
9545                                    }
9546                                };
9547                            }
9548                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9549                                    + " for user " + users[j]);
9550                            broadcastIntentLocked(null, null, intent, null, finisher,
9551                                    0, null, null, null, AppOpsManager.OP_NONE,
9552                                    true, false, MY_PID, Process.SYSTEM_UID,
9553                                    users[j]);
9554                            if (finisher != null) {
9555                                mWaitingUpdate = true;
9556                            }
9557                        }
9558                    }
9559                }
9560                if (mWaitingUpdate) {
9561                    return;
9562                }
9563                mDidUpdate = true;
9564            }
9565
9566            mAppOpsService.systemReady();
9567            mSystemReady = true;
9568        }
9569
9570        ArrayList<ProcessRecord> procsToKill = null;
9571        synchronized(mPidsSelfLocked) {
9572            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9573                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9574                if (!isAllowedWhileBooting(proc.info)){
9575                    if (procsToKill == null) {
9576                        procsToKill = new ArrayList<ProcessRecord>();
9577                    }
9578                    procsToKill.add(proc);
9579                }
9580            }
9581        }
9582
9583        synchronized(this) {
9584            if (procsToKill != null) {
9585                for (int i=procsToKill.size()-1; i>=0; i--) {
9586                    ProcessRecord proc = procsToKill.get(i);
9587                    Slog.i(TAG, "Removing system update proc: " + proc);
9588                    removeProcessLocked(proc, true, false, "system update done");
9589                }
9590            }
9591
9592            // Now that we have cleaned up any update processes, we
9593            // are ready to start launching real processes and know that
9594            // we won't trample on them any more.
9595            mProcessesReady = true;
9596        }
9597
9598        Slog.i(TAG, "System now ready");
9599        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9600            SystemClock.uptimeMillis());
9601
9602        synchronized(this) {
9603            // Make sure we have no pre-ready processes sitting around.
9604
9605            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9606                ResolveInfo ri = mContext.getPackageManager()
9607                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9608                                STOCK_PM_FLAGS);
9609                CharSequence errorMsg = null;
9610                if (ri != null) {
9611                    ActivityInfo ai = ri.activityInfo;
9612                    ApplicationInfo app = ai.applicationInfo;
9613                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9614                        mTopAction = Intent.ACTION_FACTORY_TEST;
9615                        mTopData = null;
9616                        mTopComponent = new ComponentName(app.packageName,
9617                                ai.name);
9618                    } else {
9619                        errorMsg = mContext.getResources().getText(
9620                                com.android.internal.R.string.factorytest_not_system);
9621                    }
9622                } else {
9623                    errorMsg = mContext.getResources().getText(
9624                            com.android.internal.R.string.factorytest_no_action);
9625                }
9626                if (errorMsg != null) {
9627                    mTopAction = null;
9628                    mTopData = null;
9629                    mTopComponent = null;
9630                    Message msg = Message.obtain();
9631                    msg.what = SHOW_FACTORY_ERROR_MSG;
9632                    msg.getData().putCharSequence("msg", errorMsg);
9633                    mHandler.sendMessage(msg);
9634                }
9635            }
9636        }
9637
9638        retrieveSettings();
9639
9640        synchronized (this) {
9641            readGrantedUriPermissionsLocked();
9642        }
9643
9644        if (goingCallback != null) goingCallback.run();
9645
9646        mSystemServiceManager.startUser(mCurrentUserId);
9647
9648        synchronized (this) {
9649            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9650                try {
9651                    List apps = AppGlobals.getPackageManager().
9652                        getPersistentApplications(STOCK_PM_FLAGS);
9653                    if (apps != null) {
9654                        int N = apps.size();
9655                        int i;
9656                        for (i=0; i<N; i++) {
9657                            ApplicationInfo info
9658                                = (ApplicationInfo)apps.get(i);
9659                            if (info != null &&
9660                                    !info.packageName.equals("android")) {
9661                                addAppLocked(info, false);
9662                            }
9663                        }
9664                    }
9665                } catch (RemoteException ex) {
9666                    // pm is in same process, this will never happen.
9667                }
9668            }
9669
9670            // Start up initial activity.
9671            mBooting = true;
9672
9673            try {
9674                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9675                    Message msg = Message.obtain();
9676                    msg.what = SHOW_UID_ERROR_MSG;
9677                    mHandler.sendMessage(msg);
9678                }
9679            } catch (RemoteException e) {
9680            }
9681
9682            long ident = Binder.clearCallingIdentity();
9683            try {
9684                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9685                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9686                        | Intent.FLAG_RECEIVER_FOREGROUND);
9687                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9688                broadcastIntentLocked(null, null, intent,
9689                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9690                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9691                intent = new Intent(Intent.ACTION_USER_STARTING);
9692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9693                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9694                broadcastIntentLocked(null, null, intent,
9695                        null, new IIntentReceiver.Stub() {
9696                            @Override
9697                            public void performReceive(Intent intent, int resultCode, String data,
9698                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9699                                    throws RemoteException {
9700                            }
9701                        }, 0, null, null,
9702                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9703                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9704            } catch (Throwable t) {
9705                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9706            } finally {
9707                Binder.restoreCallingIdentity(ident);
9708            }
9709            mStackSupervisor.resumeTopActivitiesLocked();
9710            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9711        }
9712    }
9713
9714    private boolean makeAppCrashingLocked(ProcessRecord app,
9715            String shortMsg, String longMsg, String stackTrace) {
9716        app.crashing = true;
9717        app.crashingReport = generateProcessError(app,
9718                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9719        startAppProblemLocked(app);
9720        app.stopFreezingAllLocked();
9721        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9722    }
9723
9724    private void makeAppNotRespondingLocked(ProcessRecord app,
9725            String activity, String shortMsg, String longMsg) {
9726        app.notResponding = true;
9727        app.notRespondingReport = generateProcessError(app,
9728                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9729                activity, shortMsg, longMsg, null);
9730        startAppProblemLocked(app);
9731        app.stopFreezingAllLocked();
9732    }
9733
9734    /**
9735     * Generate a process error record, suitable for attachment to a ProcessRecord.
9736     *
9737     * @param app The ProcessRecord in which the error occurred.
9738     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9739     *                      ActivityManager.AppErrorStateInfo
9740     * @param activity The activity associated with the crash, if known.
9741     * @param shortMsg Short message describing the crash.
9742     * @param longMsg Long message describing the crash.
9743     * @param stackTrace Full crash stack trace, may be null.
9744     *
9745     * @return Returns a fully-formed AppErrorStateInfo record.
9746     */
9747    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9748            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9749        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9750
9751        report.condition = condition;
9752        report.processName = app.processName;
9753        report.pid = app.pid;
9754        report.uid = app.info.uid;
9755        report.tag = activity;
9756        report.shortMsg = shortMsg;
9757        report.longMsg = longMsg;
9758        report.stackTrace = stackTrace;
9759
9760        return report;
9761    }
9762
9763    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9764        synchronized (this) {
9765            app.crashing = false;
9766            app.crashingReport = null;
9767            app.notResponding = false;
9768            app.notRespondingReport = null;
9769            if (app.anrDialog == fromDialog) {
9770                app.anrDialog = null;
9771            }
9772            if (app.waitDialog == fromDialog) {
9773                app.waitDialog = null;
9774            }
9775            if (app.pid > 0 && app.pid != MY_PID) {
9776                handleAppCrashLocked(app, null, null, null);
9777                killUnneededProcessLocked(app, "user request after error");
9778            }
9779        }
9780    }
9781
9782    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9783            String stackTrace) {
9784        long now = SystemClock.uptimeMillis();
9785
9786        Long crashTime;
9787        if (!app.isolated) {
9788            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9789        } else {
9790            crashTime = null;
9791        }
9792        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9793            // This process loses!
9794            Slog.w(TAG, "Process " + app.info.processName
9795                    + " has crashed too many times: killing!");
9796            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9797                    app.userId, app.info.processName, app.uid);
9798            mStackSupervisor.handleAppCrashLocked(app);
9799            if (!app.persistent) {
9800                // We don't want to start this process again until the user
9801                // explicitly does so...  but for persistent process, we really
9802                // need to keep it running.  If a persistent process is actually
9803                // repeatedly crashing, then badness for everyone.
9804                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9805                        app.info.processName);
9806                if (!app.isolated) {
9807                    // XXX We don't have a way to mark isolated processes
9808                    // as bad, since they don't have a peristent identity.
9809                    mBadProcesses.put(app.info.processName, app.uid,
9810                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9811                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9812                }
9813                app.bad = true;
9814                app.removed = true;
9815                // Don't let services in this process be restarted and potentially
9816                // annoy the user repeatedly.  Unless it is persistent, since those
9817                // processes run critical code.
9818                removeProcessLocked(app, false, false, "crash");
9819                mStackSupervisor.resumeTopActivitiesLocked();
9820                return false;
9821            }
9822            mStackSupervisor.resumeTopActivitiesLocked();
9823        } else {
9824            mStackSupervisor.finishTopRunningActivityLocked(app);
9825        }
9826
9827        // Bump up the crash count of any services currently running in the proc.
9828        for (int i=app.services.size()-1; i>=0; i--) {
9829            // Any services running in the application need to be placed
9830            // back in the pending list.
9831            ServiceRecord sr = app.services.valueAt(i);
9832            sr.crashCount++;
9833        }
9834
9835        // If the crashing process is what we consider to be the "home process" and it has been
9836        // replaced by a third-party app, clear the package preferred activities from packages
9837        // with a home activity running in the process to prevent a repeatedly crashing app
9838        // from blocking the user to manually clear the list.
9839        final ArrayList<ActivityRecord> activities = app.activities;
9840        if (app == mHomeProcess && activities.size() > 0
9841                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9842            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9843                final ActivityRecord r = activities.get(activityNdx);
9844                if (r.isHomeActivity()) {
9845                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9846                    try {
9847                        ActivityThread.getPackageManager()
9848                                .clearPackagePreferredActivities(r.packageName);
9849                    } catch (RemoteException c) {
9850                        // pm is in same process, this will never happen.
9851                    }
9852                }
9853            }
9854        }
9855
9856        if (!app.isolated) {
9857            // XXX Can't keep track of crash times for isolated processes,
9858            // because they don't have a perisistent identity.
9859            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9860        }
9861
9862        return true;
9863    }
9864
9865    void startAppProblemLocked(ProcessRecord app) {
9866        if (app.userId == mCurrentUserId) {
9867            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9868                    mContext, app.info.packageName, app.info.flags);
9869        } else {
9870            // If this app is not running under the current user, then we
9871            // can't give it a report button because that would require
9872            // launching the report UI under a different user.
9873            app.errorReportReceiver = null;
9874        }
9875        skipCurrentReceiverLocked(app);
9876    }
9877
9878    void skipCurrentReceiverLocked(ProcessRecord app) {
9879        for (BroadcastQueue queue : mBroadcastQueues) {
9880            queue.skipCurrentReceiverLocked(app);
9881        }
9882    }
9883
9884    /**
9885     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9886     * The application process will exit immediately after this call returns.
9887     * @param app object of the crashing app, null for the system server
9888     * @param crashInfo describing the exception
9889     */
9890    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9891        ProcessRecord r = findAppProcess(app, "Crash");
9892        final String processName = app == null ? "system_server"
9893                : (r == null ? "unknown" : r.processName);
9894
9895        handleApplicationCrashInner("crash", r, processName, crashInfo);
9896    }
9897
9898    /* Native crash reporting uses this inner version because it needs to be somewhat
9899     * decoupled from the AM-managed cleanup lifecycle
9900     */
9901    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9902            ApplicationErrorReport.CrashInfo crashInfo) {
9903        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9904                UserHandle.getUserId(Binder.getCallingUid()), processName,
9905                r == null ? -1 : r.info.flags,
9906                crashInfo.exceptionClassName,
9907                crashInfo.exceptionMessage,
9908                crashInfo.throwFileName,
9909                crashInfo.throwLineNumber);
9910
9911        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9912
9913        crashApplication(r, crashInfo);
9914    }
9915
9916    public void handleApplicationStrictModeViolation(
9917            IBinder app,
9918            int violationMask,
9919            StrictMode.ViolationInfo info) {
9920        ProcessRecord r = findAppProcess(app, "StrictMode");
9921        if (r == null) {
9922            return;
9923        }
9924
9925        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9926            Integer stackFingerprint = info.hashCode();
9927            boolean logIt = true;
9928            synchronized (mAlreadyLoggedViolatedStacks) {
9929                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9930                    logIt = false;
9931                    // TODO: sub-sample into EventLog for these, with
9932                    // the info.durationMillis?  Then we'd get
9933                    // the relative pain numbers, without logging all
9934                    // the stack traces repeatedly.  We'd want to do
9935                    // likewise in the client code, which also does
9936                    // dup suppression, before the Binder call.
9937                } else {
9938                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9939                        mAlreadyLoggedViolatedStacks.clear();
9940                    }
9941                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9942                }
9943            }
9944            if (logIt) {
9945                logStrictModeViolationToDropBox(r, info);
9946            }
9947        }
9948
9949        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9950            AppErrorResult result = new AppErrorResult();
9951            synchronized (this) {
9952                final long origId = Binder.clearCallingIdentity();
9953
9954                Message msg = Message.obtain();
9955                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9956                HashMap<String, Object> data = new HashMap<String, Object>();
9957                data.put("result", result);
9958                data.put("app", r);
9959                data.put("violationMask", violationMask);
9960                data.put("info", info);
9961                msg.obj = data;
9962                mHandler.sendMessage(msg);
9963
9964                Binder.restoreCallingIdentity(origId);
9965            }
9966            int res = result.get();
9967            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9968        }
9969    }
9970
9971    // Depending on the policy in effect, there could be a bunch of
9972    // these in quick succession so we try to batch these together to
9973    // minimize disk writes, number of dropbox entries, and maximize
9974    // compression, by having more fewer, larger records.
9975    private void logStrictModeViolationToDropBox(
9976            ProcessRecord process,
9977            StrictMode.ViolationInfo info) {
9978        if (info == null) {
9979            return;
9980        }
9981        final boolean isSystemApp = process == null ||
9982                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9983                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9984        final String processName = process == null ? "unknown" : process.processName;
9985        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9986        final DropBoxManager dbox = (DropBoxManager)
9987                mContext.getSystemService(Context.DROPBOX_SERVICE);
9988
9989        // Exit early if the dropbox isn't configured to accept this report type.
9990        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9991
9992        boolean bufferWasEmpty;
9993        boolean needsFlush;
9994        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9995        synchronized (sb) {
9996            bufferWasEmpty = sb.length() == 0;
9997            appendDropBoxProcessHeaders(process, processName, sb);
9998            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9999            sb.append("System-App: ").append(isSystemApp).append("\n");
10000            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10001            if (info.violationNumThisLoop != 0) {
10002                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10003            }
10004            if (info.numAnimationsRunning != 0) {
10005                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10006            }
10007            if (info.broadcastIntentAction != null) {
10008                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10009            }
10010            if (info.durationMillis != -1) {
10011                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10012            }
10013            if (info.numInstances != -1) {
10014                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10015            }
10016            if (info.tags != null) {
10017                for (String tag : info.tags) {
10018                    sb.append("Span-Tag: ").append(tag).append("\n");
10019                }
10020            }
10021            sb.append("\n");
10022            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10023                sb.append(info.crashInfo.stackTrace);
10024            }
10025            sb.append("\n");
10026
10027            // Only buffer up to ~64k.  Various logging bits truncate
10028            // things at 128k.
10029            needsFlush = (sb.length() > 64 * 1024);
10030        }
10031
10032        // Flush immediately if the buffer's grown too large, or this
10033        // is a non-system app.  Non-system apps are isolated with a
10034        // different tag & policy and not batched.
10035        //
10036        // Batching is useful during internal testing with
10037        // StrictMode settings turned up high.  Without batching,
10038        // thousands of separate files could be created on boot.
10039        if (!isSystemApp || needsFlush) {
10040            new Thread("Error dump: " + dropboxTag) {
10041                @Override
10042                public void run() {
10043                    String report;
10044                    synchronized (sb) {
10045                        report = sb.toString();
10046                        sb.delete(0, sb.length());
10047                        sb.trimToSize();
10048                    }
10049                    if (report.length() != 0) {
10050                        dbox.addText(dropboxTag, report);
10051                    }
10052                }
10053            }.start();
10054            return;
10055        }
10056
10057        // System app batching:
10058        if (!bufferWasEmpty) {
10059            // An existing dropbox-writing thread is outstanding, so
10060            // we don't need to start it up.  The existing thread will
10061            // catch the buffer appends we just did.
10062            return;
10063        }
10064
10065        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10066        // (After this point, we shouldn't access AMS internal data structures.)
10067        new Thread("Error dump: " + dropboxTag) {
10068            @Override
10069            public void run() {
10070                // 5 second sleep to let stacks arrive and be batched together
10071                try {
10072                    Thread.sleep(5000);  // 5 seconds
10073                } catch (InterruptedException e) {}
10074
10075                String errorReport;
10076                synchronized (mStrictModeBuffer) {
10077                    errorReport = mStrictModeBuffer.toString();
10078                    if (errorReport.length() == 0) {
10079                        return;
10080                    }
10081                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10082                    mStrictModeBuffer.trimToSize();
10083                }
10084                dbox.addText(dropboxTag, errorReport);
10085            }
10086        }.start();
10087    }
10088
10089    /**
10090     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10091     * @param app object of the crashing app, null for the system server
10092     * @param tag reported by the caller
10093     * @param crashInfo describing the context of the error
10094     * @return true if the process should exit immediately (WTF is fatal)
10095     */
10096    public boolean handleApplicationWtf(IBinder app, String tag,
10097            ApplicationErrorReport.CrashInfo crashInfo) {
10098        ProcessRecord r = findAppProcess(app, "WTF");
10099        final String processName = app == null ? "system_server"
10100                : (r == null ? "unknown" : r.processName);
10101
10102        EventLog.writeEvent(EventLogTags.AM_WTF,
10103                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10104                processName,
10105                r == null ? -1 : r.info.flags,
10106                tag, crashInfo.exceptionMessage);
10107
10108        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10109
10110        if (r != null && r.pid != Process.myPid() &&
10111                Settings.Global.getInt(mContext.getContentResolver(),
10112                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10113            crashApplication(r, crashInfo);
10114            return true;
10115        } else {
10116            return false;
10117        }
10118    }
10119
10120    /**
10121     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10122     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10123     */
10124    private ProcessRecord findAppProcess(IBinder app, String reason) {
10125        if (app == null) {
10126            return null;
10127        }
10128
10129        synchronized (this) {
10130            final int NP = mProcessNames.getMap().size();
10131            for (int ip=0; ip<NP; ip++) {
10132                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10133                final int NA = apps.size();
10134                for (int ia=0; ia<NA; ia++) {
10135                    ProcessRecord p = apps.valueAt(ia);
10136                    if (p.thread != null && p.thread.asBinder() == app) {
10137                        return p;
10138                    }
10139                }
10140            }
10141
10142            Slog.w(TAG, "Can't find mystery application for " + reason
10143                    + " from pid=" + Binder.getCallingPid()
10144                    + " uid=" + Binder.getCallingUid() + ": " + app);
10145            return null;
10146        }
10147    }
10148
10149    /**
10150     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10151     * to append various headers to the dropbox log text.
10152     */
10153    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10154            StringBuilder sb) {
10155        // Watchdog thread ends up invoking this function (with
10156        // a null ProcessRecord) to add the stack file to dropbox.
10157        // Do not acquire a lock on this (am) in such cases, as it
10158        // could cause a potential deadlock, if and when watchdog
10159        // is invoked due to unavailability of lock on am and it
10160        // would prevent watchdog from killing system_server.
10161        if (process == null) {
10162            sb.append("Process: ").append(processName).append("\n");
10163            return;
10164        }
10165        // Note: ProcessRecord 'process' is guarded by the service
10166        // instance.  (notably process.pkgList, which could otherwise change
10167        // concurrently during execution of this method)
10168        synchronized (this) {
10169            sb.append("Process: ").append(processName).append("\n");
10170            int flags = process.info.flags;
10171            IPackageManager pm = AppGlobals.getPackageManager();
10172            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10173            for (int ip=0; ip<process.pkgList.size(); ip++) {
10174                String pkg = process.pkgList.keyAt(ip);
10175                sb.append("Package: ").append(pkg);
10176                try {
10177                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10178                    if (pi != null) {
10179                        sb.append(" v").append(pi.versionCode);
10180                        if (pi.versionName != null) {
10181                            sb.append(" (").append(pi.versionName).append(")");
10182                        }
10183                    }
10184                } catch (RemoteException e) {
10185                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10186                }
10187                sb.append("\n");
10188            }
10189        }
10190    }
10191
10192    private static String processClass(ProcessRecord process) {
10193        if (process == null || process.pid == MY_PID) {
10194            return "system_server";
10195        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10196            return "system_app";
10197        } else {
10198            return "data_app";
10199        }
10200    }
10201
10202    /**
10203     * Write a description of an error (crash, WTF, ANR) to the drop box.
10204     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10205     * @param process which caused the error, null means the system server
10206     * @param activity which triggered the error, null if unknown
10207     * @param parent activity related to the error, null if unknown
10208     * @param subject line related to the error, null if absent
10209     * @param report in long form describing the error, null if absent
10210     * @param logFile to include in the report, null if none
10211     * @param crashInfo giving an application stack trace, null if absent
10212     */
10213    public void addErrorToDropBox(String eventType,
10214            ProcessRecord process, String processName, ActivityRecord activity,
10215            ActivityRecord parent, String subject,
10216            final String report, final File logFile,
10217            final ApplicationErrorReport.CrashInfo crashInfo) {
10218        // NOTE -- this must never acquire the ActivityManagerService lock,
10219        // otherwise the watchdog may be prevented from resetting the system.
10220
10221        final String dropboxTag = processClass(process) + "_" + eventType;
10222        final DropBoxManager dbox = (DropBoxManager)
10223                mContext.getSystemService(Context.DROPBOX_SERVICE);
10224
10225        // Exit early if the dropbox isn't configured to accept this report type.
10226        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10227
10228        final StringBuilder sb = new StringBuilder(1024);
10229        appendDropBoxProcessHeaders(process, processName, sb);
10230        if (activity != null) {
10231            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10232        }
10233        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10234            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10235        }
10236        if (parent != null && parent != activity) {
10237            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10238        }
10239        if (subject != null) {
10240            sb.append("Subject: ").append(subject).append("\n");
10241        }
10242        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10243        if (Debug.isDebuggerConnected()) {
10244            sb.append("Debugger: Connected\n");
10245        }
10246        sb.append("\n");
10247
10248        // Do the rest in a worker thread to avoid blocking the caller on I/O
10249        // (After this point, we shouldn't access AMS internal data structures.)
10250        Thread worker = new Thread("Error dump: " + dropboxTag) {
10251            @Override
10252            public void run() {
10253                if (report != null) {
10254                    sb.append(report);
10255                }
10256                if (logFile != null) {
10257                    try {
10258                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10259                                    "\n\n[[TRUNCATED]]"));
10260                    } catch (IOException e) {
10261                        Slog.e(TAG, "Error reading " + logFile, e);
10262                    }
10263                }
10264                if (crashInfo != null && crashInfo.stackTrace != null) {
10265                    sb.append(crashInfo.stackTrace);
10266                }
10267
10268                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10269                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10270                if (lines > 0) {
10271                    sb.append("\n");
10272
10273                    // Merge several logcat streams, and take the last N lines
10274                    InputStreamReader input = null;
10275                    try {
10276                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10277                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10278                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10279
10280                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10281                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10282                        input = new InputStreamReader(logcat.getInputStream());
10283
10284                        int num;
10285                        char[] buf = new char[8192];
10286                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10287                    } catch (IOException e) {
10288                        Slog.e(TAG, "Error running logcat", e);
10289                    } finally {
10290                        if (input != null) try { input.close(); } catch (IOException e) {}
10291                    }
10292                }
10293
10294                dbox.addText(dropboxTag, sb.toString());
10295            }
10296        };
10297
10298        if (process == null) {
10299            // If process is null, we are being called from some internal code
10300            // and may be about to die -- run this synchronously.
10301            worker.run();
10302        } else {
10303            worker.start();
10304        }
10305    }
10306
10307    /**
10308     * Bring up the "unexpected error" dialog box for a crashing app.
10309     * Deal with edge cases (intercepts from instrumented applications,
10310     * ActivityController, error intent receivers, that sort of thing).
10311     * @param r the application crashing
10312     * @param crashInfo describing the failure
10313     */
10314    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10315        long timeMillis = System.currentTimeMillis();
10316        String shortMsg = crashInfo.exceptionClassName;
10317        String longMsg = crashInfo.exceptionMessage;
10318        String stackTrace = crashInfo.stackTrace;
10319        if (shortMsg != null && longMsg != null) {
10320            longMsg = shortMsg + ": " + longMsg;
10321        } else if (shortMsg != null) {
10322            longMsg = shortMsg;
10323        }
10324
10325        AppErrorResult result = new AppErrorResult();
10326        synchronized (this) {
10327            if (mController != null) {
10328                try {
10329                    String name = r != null ? r.processName : null;
10330                    int pid = r != null ? r.pid : Binder.getCallingPid();
10331                    if (!mController.appCrashed(name, pid,
10332                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10333                        Slog.w(TAG, "Force-killing crashed app " + name
10334                                + " at watcher's request");
10335                        Process.killProcess(pid);
10336                        return;
10337                    }
10338                } catch (RemoteException e) {
10339                    mController = null;
10340                    Watchdog.getInstance().setActivityController(null);
10341                }
10342            }
10343
10344            final long origId = Binder.clearCallingIdentity();
10345
10346            // If this process is running instrumentation, finish it.
10347            if (r != null && r.instrumentationClass != null) {
10348                Slog.w(TAG, "Error in app " + r.processName
10349                      + " running instrumentation " + r.instrumentationClass + ":");
10350                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10351                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10352                Bundle info = new Bundle();
10353                info.putString("shortMsg", shortMsg);
10354                info.putString("longMsg", longMsg);
10355                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10356                Binder.restoreCallingIdentity(origId);
10357                return;
10358            }
10359
10360            // If we can't identify the process or it's already exceeded its crash quota,
10361            // quit right away without showing a crash dialog.
10362            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10363                Binder.restoreCallingIdentity(origId);
10364                return;
10365            }
10366
10367            Message msg = Message.obtain();
10368            msg.what = SHOW_ERROR_MSG;
10369            HashMap data = new HashMap();
10370            data.put("result", result);
10371            data.put("app", r);
10372            msg.obj = data;
10373            mHandler.sendMessage(msg);
10374
10375            Binder.restoreCallingIdentity(origId);
10376        }
10377
10378        int res = result.get();
10379
10380        Intent appErrorIntent = null;
10381        synchronized (this) {
10382            if (r != null && !r.isolated) {
10383                // XXX Can't keep track of crash time for isolated processes,
10384                // since they don't have a persistent identity.
10385                mProcessCrashTimes.put(r.info.processName, r.uid,
10386                        SystemClock.uptimeMillis());
10387            }
10388            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10389                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10390            }
10391        }
10392
10393        if (appErrorIntent != null) {
10394            try {
10395                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10396            } catch (ActivityNotFoundException e) {
10397                Slog.w(TAG, "bug report receiver dissappeared", e);
10398            }
10399        }
10400    }
10401
10402    Intent createAppErrorIntentLocked(ProcessRecord r,
10403            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10404        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10405        if (report == null) {
10406            return null;
10407        }
10408        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10409        result.setComponent(r.errorReportReceiver);
10410        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10411        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10412        return result;
10413    }
10414
10415    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10416            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10417        if (r.errorReportReceiver == null) {
10418            return null;
10419        }
10420
10421        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10422            return null;
10423        }
10424
10425        ApplicationErrorReport report = new ApplicationErrorReport();
10426        report.packageName = r.info.packageName;
10427        report.installerPackageName = r.errorReportReceiver.getPackageName();
10428        report.processName = r.processName;
10429        report.time = timeMillis;
10430        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10431
10432        if (r.crashing || r.forceCrashReport) {
10433            report.type = ApplicationErrorReport.TYPE_CRASH;
10434            report.crashInfo = crashInfo;
10435        } else if (r.notResponding) {
10436            report.type = ApplicationErrorReport.TYPE_ANR;
10437            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10438
10439            report.anrInfo.activity = r.notRespondingReport.tag;
10440            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10441            report.anrInfo.info = r.notRespondingReport.longMsg;
10442        }
10443
10444        return report;
10445    }
10446
10447    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10448        enforceNotIsolatedCaller("getProcessesInErrorState");
10449        // assume our apps are happy - lazy create the list
10450        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10451
10452        final boolean allUsers = ActivityManager.checkUidPermission(
10453                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10454                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10455        int userId = UserHandle.getUserId(Binder.getCallingUid());
10456
10457        synchronized (this) {
10458
10459            // iterate across all processes
10460            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10461                ProcessRecord app = mLruProcesses.get(i);
10462                if (!allUsers && app.userId != userId) {
10463                    continue;
10464                }
10465                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10466                    // This one's in trouble, so we'll generate a report for it
10467                    // crashes are higher priority (in case there's a crash *and* an anr)
10468                    ActivityManager.ProcessErrorStateInfo report = null;
10469                    if (app.crashing) {
10470                        report = app.crashingReport;
10471                    } else if (app.notResponding) {
10472                        report = app.notRespondingReport;
10473                    }
10474
10475                    if (report != null) {
10476                        if (errList == null) {
10477                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10478                        }
10479                        errList.add(report);
10480                    } else {
10481                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10482                                " crashing = " + app.crashing +
10483                                " notResponding = " + app.notResponding);
10484                    }
10485                }
10486            }
10487        }
10488
10489        return errList;
10490    }
10491
10492    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10493        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10494            if (currApp != null) {
10495                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10496            }
10497            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10498        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10499            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10500        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10501            if (currApp != null) {
10502                currApp.lru = 0;
10503            }
10504            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10505        } else if (adj >= ProcessList.SERVICE_ADJ) {
10506            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10507        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10508            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10509        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10510            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10511        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10512            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10513        } else {
10514            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10515        }
10516    }
10517
10518    private void fillInProcMemInfo(ProcessRecord app,
10519            ActivityManager.RunningAppProcessInfo outInfo) {
10520        outInfo.pid = app.pid;
10521        outInfo.uid = app.info.uid;
10522        if (mHeavyWeightProcess == app) {
10523            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10524        }
10525        if (app.persistent) {
10526            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10527        }
10528        if (app.activities.size() > 0) {
10529            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10530        }
10531        outInfo.lastTrimLevel = app.trimMemoryLevel;
10532        int adj = app.curAdj;
10533        outInfo.importance = oomAdjToImportance(adj, outInfo);
10534        outInfo.importanceReasonCode = app.adjTypeCode;
10535        outInfo.processState = app.curProcState;
10536    }
10537
10538    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10539        enforceNotIsolatedCaller("getRunningAppProcesses");
10540        // Lazy instantiation of list
10541        List<ActivityManager.RunningAppProcessInfo> runList = null;
10542        final boolean allUsers = ActivityManager.checkUidPermission(
10543                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10544                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10545        int userId = UserHandle.getUserId(Binder.getCallingUid());
10546        synchronized (this) {
10547            // Iterate across all processes
10548            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10549                ProcessRecord app = mLruProcesses.get(i);
10550                if (!allUsers && app.userId != userId) {
10551                    continue;
10552                }
10553                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10554                    // Generate process state info for running application
10555                    ActivityManager.RunningAppProcessInfo currApp =
10556                        new ActivityManager.RunningAppProcessInfo(app.processName,
10557                                app.pid, app.getPackageList());
10558                    fillInProcMemInfo(app, currApp);
10559                    if (app.adjSource instanceof ProcessRecord) {
10560                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10561                        currApp.importanceReasonImportance = oomAdjToImportance(
10562                                app.adjSourceOom, null);
10563                    } else if (app.adjSource instanceof ActivityRecord) {
10564                        ActivityRecord r = (ActivityRecord)app.adjSource;
10565                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10566                    }
10567                    if (app.adjTarget instanceof ComponentName) {
10568                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10569                    }
10570                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10571                    //        + " lru=" + currApp.lru);
10572                    if (runList == null) {
10573                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10574                    }
10575                    runList.add(currApp);
10576                }
10577            }
10578        }
10579        return runList;
10580    }
10581
10582    public List<ApplicationInfo> getRunningExternalApplications() {
10583        enforceNotIsolatedCaller("getRunningExternalApplications");
10584        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10585        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10586        if (runningApps != null && runningApps.size() > 0) {
10587            Set<String> extList = new HashSet<String>();
10588            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10589                if (app.pkgList != null) {
10590                    for (String pkg : app.pkgList) {
10591                        extList.add(pkg);
10592                    }
10593                }
10594            }
10595            IPackageManager pm = AppGlobals.getPackageManager();
10596            for (String pkg : extList) {
10597                try {
10598                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10599                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10600                        retList.add(info);
10601                    }
10602                } catch (RemoteException e) {
10603                }
10604            }
10605        }
10606        return retList;
10607    }
10608
10609    @Override
10610    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10611        enforceNotIsolatedCaller("getMyMemoryState");
10612        synchronized (this) {
10613            ProcessRecord proc;
10614            synchronized (mPidsSelfLocked) {
10615                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10616            }
10617            fillInProcMemInfo(proc, outInfo);
10618        }
10619    }
10620
10621    @Override
10622    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10623        if (checkCallingPermission(android.Manifest.permission.DUMP)
10624                != PackageManager.PERMISSION_GRANTED) {
10625            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10626                    + Binder.getCallingPid()
10627                    + ", uid=" + Binder.getCallingUid()
10628                    + " without permission "
10629                    + android.Manifest.permission.DUMP);
10630            return;
10631        }
10632
10633        boolean dumpAll = false;
10634        boolean dumpClient = false;
10635        String dumpPackage = null;
10636
10637        int opti = 0;
10638        while (opti < args.length) {
10639            String opt = args[opti];
10640            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10641                break;
10642            }
10643            opti++;
10644            if ("-a".equals(opt)) {
10645                dumpAll = true;
10646            } else if ("-c".equals(opt)) {
10647                dumpClient = true;
10648            } else if ("-h".equals(opt)) {
10649                pw.println("Activity manager dump options:");
10650                pw.println("  [-a] [-c] [-h] [cmd] ...");
10651                pw.println("  cmd may be one of:");
10652                pw.println("    a[ctivities]: activity stack state");
10653                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10654                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10655                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10656                pw.println("    o[om]: out of memory management");
10657                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10658                pw.println("    provider [COMP_SPEC]: provider client-side state");
10659                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10660                pw.println("    service [COMP_SPEC]: service client-side state");
10661                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10662                pw.println("    all: dump all activities");
10663                pw.println("    top: dump the top activity");
10664                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10665                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10666                pw.println("    a partial substring in a component name, a");
10667                pw.println("    hex object identifier.");
10668                pw.println("  -a: include all available server state.");
10669                pw.println("  -c: include client state.");
10670                return;
10671            } else {
10672                pw.println("Unknown argument: " + opt + "; use -h for help");
10673            }
10674        }
10675
10676        long origId = Binder.clearCallingIdentity();
10677        boolean more = false;
10678        // Is the caller requesting to dump a particular piece of data?
10679        if (opti < args.length) {
10680            String cmd = args[opti];
10681            opti++;
10682            if ("activities".equals(cmd) || "a".equals(cmd)) {
10683                synchronized (this) {
10684                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10685                }
10686            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10687                String[] newArgs;
10688                String name;
10689                if (opti >= args.length) {
10690                    name = null;
10691                    newArgs = EMPTY_STRING_ARRAY;
10692                } else {
10693                    name = args[opti];
10694                    opti++;
10695                    newArgs = new String[args.length - opti];
10696                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10697                            args.length - opti);
10698                }
10699                synchronized (this) {
10700                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10701                }
10702            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10703                String[] newArgs;
10704                String name;
10705                if (opti >= args.length) {
10706                    name = null;
10707                    newArgs = EMPTY_STRING_ARRAY;
10708                } else {
10709                    name = args[opti];
10710                    opti++;
10711                    newArgs = new String[args.length - opti];
10712                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10713                            args.length - opti);
10714                }
10715                synchronized (this) {
10716                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10717                }
10718            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10719                String[] newArgs;
10720                String name;
10721                if (opti >= args.length) {
10722                    name = null;
10723                    newArgs = EMPTY_STRING_ARRAY;
10724                } else {
10725                    name = args[opti];
10726                    opti++;
10727                    newArgs = new String[args.length - opti];
10728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10729                            args.length - opti);
10730                }
10731                synchronized (this) {
10732                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10733                }
10734            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10735                synchronized (this) {
10736                    dumpOomLocked(fd, pw, args, opti, true);
10737                }
10738            } else if ("provider".equals(cmd)) {
10739                String[] newArgs;
10740                String name;
10741                if (opti >= args.length) {
10742                    name = null;
10743                    newArgs = EMPTY_STRING_ARRAY;
10744                } else {
10745                    name = args[opti];
10746                    opti++;
10747                    newArgs = new String[args.length - opti];
10748                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10749                }
10750                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10751                    pw.println("No providers match: " + name);
10752                    pw.println("Use -h for help.");
10753                }
10754            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10755                synchronized (this) {
10756                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10757                }
10758            } else if ("service".equals(cmd)) {
10759                String[] newArgs;
10760                String name;
10761                if (opti >= args.length) {
10762                    name = null;
10763                    newArgs = EMPTY_STRING_ARRAY;
10764                } else {
10765                    name = args[opti];
10766                    opti++;
10767                    newArgs = new String[args.length - opti];
10768                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10769                            args.length - opti);
10770                }
10771                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10772                    pw.println("No services match: " + name);
10773                    pw.println("Use -h for help.");
10774                }
10775            } else if ("package".equals(cmd)) {
10776                String[] newArgs;
10777                if (opti >= args.length) {
10778                    pw.println("package: no package name specified");
10779                    pw.println("Use -h for help.");
10780                } else {
10781                    dumpPackage = args[opti];
10782                    opti++;
10783                    newArgs = new String[args.length - opti];
10784                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10785                            args.length - opti);
10786                    args = newArgs;
10787                    opti = 0;
10788                    more = true;
10789                }
10790            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10791                synchronized (this) {
10792                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10793                }
10794            } else {
10795                // Dumping a single activity?
10796                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10797                    pw.println("Bad activity command, or no activities match: " + cmd);
10798                    pw.println("Use -h for help.");
10799                }
10800            }
10801            if (!more) {
10802                Binder.restoreCallingIdentity(origId);
10803                return;
10804            }
10805        }
10806
10807        // No piece of data specified, dump everything.
10808        synchronized (this) {
10809            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10810            pw.println();
10811            if (dumpAll) {
10812                pw.println("-------------------------------------------------------------------------------");
10813            }
10814            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10815            pw.println();
10816            if (dumpAll) {
10817                pw.println("-------------------------------------------------------------------------------");
10818            }
10819            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10820            pw.println();
10821            if (dumpAll) {
10822                pw.println("-------------------------------------------------------------------------------");
10823            }
10824            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10825            pw.println();
10826            if (dumpAll) {
10827                pw.println("-------------------------------------------------------------------------------");
10828            }
10829            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10830            pw.println();
10831            if (dumpAll) {
10832                pw.println("-------------------------------------------------------------------------------");
10833            }
10834            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10835        }
10836        Binder.restoreCallingIdentity(origId);
10837    }
10838
10839    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10840            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10841        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10842
10843        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10844                dumpPackage);
10845        boolean needSep = printedAnything;
10846
10847        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10848                dumpPackage, needSep, "  mFocusedActivity: ");
10849        if (printed) {
10850            printedAnything = true;
10851            needSep = false;
10852        }
10853
10854        if (dumpPackage == null) {
10855            if (needSep) {
10856                pw.println();
10857            }
10858            needSep = true;
10859            printedAnything = true;
10860            mStackSupervisor.dump(pw, "  ");
10861        }
10862
10863        if (mRecentTasks.size() > 0) {
10864            boolean printedHeader = false;
10865
10866            final int N = mRecentTasks.size();
10867            for (int i=0; i<N; i++) {
10868                TaskRecord tr = mRecentTasks.get(i);
10869                if (dumpPackage != null) {
10870                    if (tr.realActivity == null ||
10871                            !dumpPackage.equals(tr.realActivity)) {
10872                        continue;
10873                    }
10874                }
10875                if (!printedHeader) {
10876                    if (needSep) {
10877                        pw.println();
10878                    }
10879                    pw.println("  Recent tasks:");
10880                    printedHeader = true;
10881                    printedAnything = true;
10882                }
10883                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10884                        pw.println(tr);
10885                if (dumpAll) {
10886                    mRecentTasks.get(i).dump(pw, "    ");
10887                }
10888            }
10889        }
10890
10891        if (!printedAnything) {
10892            pw.println("  (nothing)");
10893        }
10894    }
10895
10896    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10897            int opti, boolean dumpAll, String dumpPackage) {
10898        boolean needSep = false;
10899        boolean printedAnything = false;
10900        int numPers = 0;
10901
10902        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10903
10904        if (dumpAll) {
10905            final int NP = mProcessNames.getMap().size();
10906            for (int ip=0; ip<NP; ip++) {
10907                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10908                final int NA = procs.size();
10909                for (int ia=0; ia<NA; ia++) {
10910                    ProcessRecord r = procs.valueAt(ia);
10911                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10912                        continue;
10913                    }
10914                    if (!needSep) {
10915                        pw.println("  All known processes:");
10916                        needSep = true;
10917                        printedAnything = true;
10918                    }
10919                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10920                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10921                        pw.print(" "); pw.println(r);
10922                    r.dump(pw, "    ");
10923                    if (r.persistent) {
10924                        numPers++;
10925                    }
10926                }
10927            }
10928        }
10929
10930        if (mIsolatedProcesses.size() > 0) {
10931            boolean printed = false;
10932            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10933                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10934                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10935                    continue;
10936                }
10937                if (!printed) {
10938                    if (needSep) {
10939                        pw.println();
10940                    }
10941                    pw.println("  Isolated process list (sorted by uid):");
10942                    printedAnything = true;
10943                    printed = true;
10944                    needSep = true;
10945                }
10946                pw.println(String.format("%sIsolated #%2d: %s",
10947                        "    ", i, r.toString()));
10948            }
10949        }
10950
10951        if (mLruProcesses.size() > 0) {
10952            if (needSep) {
10953                pw.println();
10954            }
10955            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10956                    pw.print(" total, non-act at ");
10957                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10958                    pw.print(", non-svc at ");
10959                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10960                    pw.println("):");
10961            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10962            needSep = true;
10963            printedAnything = true;
10964        }
10965
10966        if (dumpAll || dumpPackage != null) {
10967            synchronized (mPidsSelfLocked) {
10968                boolean printed = false;
10969                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10970                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10971                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10972                        continue;
10973                    }
10974                    if (!printed) {
10975                        if (needSep) pw.println();
10976                        needSep = true;
10977                        pw.println("  PID mappings:");
10978                        printed = true;
10979                        printedAnything = true;
10980                    }
10981                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10982                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10983                }
10984            }
10985        }
10986
10987        if (mForegroundProcesses.size() > 0) {
10988            synchronized (mPidsSelfLocked) {
10989                boolean printed = false;
10990                for (int i=0; i<mForegroundProcesses.size(); i++) {
10991                    ProcessRecord r = mPidsSelfLocked.get(
10992                            mForegroundProcesses.valueAt(i).pid);
10993                    if (dumpPackage != null && (r == null
10994                            || !r.pkgList.containsKey(dumpPackage))) {
10995                        continue;
10996                    }
10997                    if (!printed) {
10998                        if (needSep) pw.println();
10999                        needSep = true;
11000                        pw.println("  Foreground Processes:");
11001                        printed = true;
11002                        printedAnything = true;
11003                    }
11004                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11005                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11006                }
11007            }
11008        }
11009
11010        if (mPersistentStartingProcesses.size() > 0) {
11011            if (needSep) pw.println();
11012            needSep = true;
11013            printedAnything = true;
11014            pw.println("  Persisent processes that are starting:");
11015            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11016                    "Starting Norm", "Restarting PERS", dumpPackage);
11017        }
11018
11019        if (mRemovedProcesses.size() > 0) {
11020            if (needSep) pw.println();
11021            needSep = true;
11022            printedAnything = true;
11023            pw.println("  Processes that are being removed:");
11024            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11025                    "Removed Norm", "Removed PERS", dumpPackage);
11026        }
11027
11028        if (mProcessesOnHold.size() > 0) {
11029            if (needSep) pw.println();
11030            needSep = true;
11031            printedAnything = true;
11032            pw.println("  Processes that are on old until the system is ready:");
11033            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11034                    "OnHold Norm", "OnHold PERS", dumpPackage);
11035        }
11036
11037        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11038
11039        if (mProcessCrashTimes.getMap().size() > 0) {
11040            boolean printed = false;
11041            long now = SystemClock.uptimeMillis();
11042            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11043            final int NP = pmap.size();
11044            for (int ip=0; ip<NP; ip++) {
11045                String pname = pmap.keyAt(ip);
11046                SparseArray<Long> uids = pmap.valueAt(ip);
11047                final int N = uids.size();
11048                for (int i=0; i<N; i++) {
11049                    int puid = uids.keyAt(i);
11050                    ProcessRecord r = mProcessNames.get(pname, puid);
11051                    if (dumpPackage != null && (r == null
11052                            || !r.pkgList.containsKey(dumpPackage))) {
11053                        continue;
11054                    }
11055                    if (!printed) {
11056                        if (needSep) pw.println();
11057                        needSep = true;
11058                        pw.println("  Time since processes crashed:");
11059                        printed = true;
11060                        printedAnything = true;
11061                    }
11062                    pw.print("    Process "); pw.print(pname);
11063                            pw.print(" uid "); pw.print(puid);
11064                            pw.print(": last crashed ");
11065                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11066                            pw.println(" ago");
11067                }
11068            }
11069        }
11070
11071        if (mBadProcesses.getMap().size() > 0) {
11072            boolean printed = false;
11073            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11074            final int NP = pmap.size();
11075            for (int ip=0; ip<NP; ip++) {
11076                String pname = pmap.keyAt(ip);
11077                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11078                final int N = uids.size();
11079                for (int i=0; i<N; i++) {
11080                    int puid = uids.keyAt(i);
11081                    ProcessRecord r = mProcessNames.get(pname, puid);
11082                    if (dumpPackage != null && (r == null
11083                            || !r.pkgList.containsKey(dumpPackage))) {
11084                        continue;
11085                    }
11086                    if (!printed) {
11087                        if (needSep) pw.println();
11088                        needSep = true;
11089                        pw.println("  Bad processes:");
11090                        printedAnything = true;
11091                    }
11092                    BadProcessInfo info = uids.valueAt(i);
11093                    pw.print("    Bad process "); pw.print(pname);
11094                            pw.print(" uid "); pw.print(puid);
11095                            pw.print(": crashed at time "); pw.println(info.time);
11096                    if (info.shortMsg != null) {
11097                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11098                    }
11099                    if (info.longMsg != null) {
11100                        pw.print("      Long msg: "); pw.println(info.longMsg);
11101                    }
11102                    if (info.stack != null) {
11103                        pw.println("      Stack:");
11104                        int lastPos = 0;
11105                        for (int pos=0; pos<info.stack.length(); pos++) {
11106                            if (info.stack.charAt(pos) == '\n') {
11107                                pw.print("        ");
11108                                pw.write(info.stack, lastPos, pos-lastPos);
11109                                pw.println();
11110                                lastPos = pos+1;
11111                            }
11112                        }
11113                        if (lastPos < info.stack.length()) {
11114                            pw.print("        ");
11115                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11116                            pw.println();
11117                        }
11118                    }
11119                }
11120            }
11121        }
11122
11123        if (dumpPackage == null) {
11124            pw.println();
11125            needSep = false;
11126            pw.println("  mStartedUsers:");
11127            for (int i=0; i<mStartedUsers.size(); i++) {
11128                UserStartedState uss = mStartedUsers.valueAt(i);
11129                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11130                        pw.print(": "); uss.dump("", pw);
11131            }
11132            pw.print("  mStartedUserArray: [");
11133            for (int i=0; i<mStartedUserArray.length; i++) {
11134                if (i > 0) pw.print(", ");
11135                pw.print(mStartedUserArray[i]);
11136            }
11137            pw.println("]");
11138            pw.print("  mUserLru: [");
11139            for (int i=0; i<mUserLru.size(); i++) {
11140                if (i > 0) pw.print(", ");
11141                pw.print(mUserLru.get(i));
11142            }
11143            pw.println("]");
11144            if (dumpAll) {
11145                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11146            }
11147        }
11148        if (mHomeProcess != null && (dumpPackage == null
11149                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11150            if (needSep) {
11151                pw.println();
11152                needSep = false;
11153            }
11154            pw.println("  mHomeProcess: " + mHomeProcess);
11155        }
11156        if (mPreviousProcess != null && (dumpPackage == null
11157                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11158            if (needSep) {
11159                pw.println();
11160                needSep = false;
11161            }
11162            pw.println("  mPreviousProcess: " + mPreviousProcess);
11163        }
11164        if (dumpAll) {
11165            StringBuilder sb = new StringBuilder(128);
11166            sb.append("  mPreviousProcessVisibleTime: ");
11167            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11168            pw.println(sb);
11169        }
11170        if (mHeavyWeightProcess != null && (dumpPackage == null
11171                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11172            if (needSep) {
11173                pw.println();
11174                needSep = false;
11175            }
11176            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11177        }
11178        if (dumpPackage == null) {
11179            pw.println("  mConfiguration: " + mConfiguration);
11180        }
11181        if (dumpAll) {
11182            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11183            if (mCompatModePackages.getPackages().size() > 0) {
11184                boolean printed = false;
11185                for (Map.Entry<String, Integer> entry
11186                        : mCompatModePackages.getPackages().entrySet()) {
11187                    String pkg = entry.getKey();
11188                    int mode = entry.getValue();
11189                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11190                        continue;
11191                    }
11192                    if (!printed) {
11193                        pw.println("  mScreenCompatPackages:");
11194                        printed = true;
11195                    }
11196                    pw.print("    "); pw.print(pkg); pw.print(": ");
11197                            pw.print(mode); pw.println();
11198                }
11199            }
11200        }
11201        if (dumpPackage == null) {
11202            if (mSleeping || mWentToSleep || mLockScreenShown) {
11203                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11204                        + " mLockScreenShown " + mLockScreenShown);
11205            }
11206            if (mShuttingDown || mRunningVoice) {
11207                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11208            }
11209        }
11210        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11211                || mOrigWaitForDebugger) {
11212            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11213                    || dumpPackage.equals(mOrigDebugApp)) {
11214                if (needSep) {
11215                    pw.println();
11216                    needSep = false;
11217                }
11218                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11219                        + " mDebugTransient=" + mDebugTransient
11220                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11221            }
11222        }
11223        if (mOpenGlTraceApp != null) {
11224            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11225                if (needSep) {
11226                    pw.println();
11227                    needSep = false;
11228                }
11229                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11230            }
11231        }
11232        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11233                || mProfileFd != null) {
11234            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11235                if (needSep) {
11236                    pw.println();
11237                    needSep = false;
11238                }
11239                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11240                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11241                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11242                        + mAutoStopProfiler);
11243            }
11244        }
11245        if (dumpPackage == null) {
11246            if (mAlwaysFinishActivities || mController != null) {
11247                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11248                        + " mController=" + mController);
11249            }
11250            if (dumpAll) {
11251                pw.println("  Total persistent processes: " + numPers);
11252                pw.println("  mProcessesReady=" + mProcessesReady
11253                        + " mSystemReady=" + mSystemReady);
11254                pw.println("  mBooting=" + mBooting
11255                        + " mBooted=" + mBooted
11256                        + " mFactoryTest=" + mFactoryTest);
11257                pw.print("  mLastPowerCheckRealtime=");
11258                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11259                        pw.println("");
11260                pw.print("  mLastPowerCheckUptime=");
11261                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11262                        pw.println("");
11263                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11264                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11265                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11266                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11267                        + " (" + mLruProcesses.size() + " total)"
11268                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11269                        + " mNumServiceProcs=" + mNumServiceProcs
11270                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11271                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11272                        + " mLastMemoryLevel" + mLastMemoryLevel
11273                        + " mLastNumProcesses" + mLastNumProcesses);
11274                long now = SystemClock.uptimeMillis();
11275                pw.print("  mLastIdleTime=");
11276                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11277                        pw.print(" mLowRamSinceLastIdle=");
11278                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11279                        pw.println();
11280            }
11281        }
11282
11283        if (!printedAnything) {
11284            pw.println("  (nothing)");
11285        }
11286    }
11287
11288    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11289            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11290        if (mProcessesToGc.size() > 0) {
11291            boolean printed = false;
11292            long now = SystemClock.uptimeMillis();
11293            for (int i=0; i<mProcessesToGc.size(); i++) {
11294                ProcessRecord proc = mProcessesToGc.get(i);
11295                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11296                    continue;
11297                }
11298                if (!printed) {
11299                    if (needSep) pw.println();
11300                    needSep = true;
11301                    pw.println("  Processes that are waiting to GC:");
11302                    printed = true;
11303                }
11304                pw.print("    Process "); pw.println(proc);
11305                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11306                        pw.print(", last gced=");
11307                        pw.print(now-proc.lastRequestedGc);
11308                        pw.print(" ms ago, last lowMem=");
11309                        pw.print(now-proc.lastLowMemory);
11310                        pw.println(" ms ago");
11311
11312            }
11313        }
11314        return needSep;
11315    }
11316
11317    void printOomLevel(PrintWriter pw, String name, int adj) {
11318        pw.print("    ");
11319        if (adj >= 0) {
11320            pw.print(' ');
11321            if (adj < 10) pw.print(' ');
11322        } else {
11323            if (adj > -10) pw.print(' ');
11324        }
11325        pw.print(adj);
11326        pw.print(": ");
11327        pw.print(name);
11328        pw.print(" (");
11329        pw.print(mProcessList.getMemLevel(adj)/1024);
11330        pw.println(" kB)");
11331    }
11332
11333    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11334            int opti, boolean dumpAll) {
11335        boolean needSep = false;
11336
11337        if (mLruProcesses.size() > 0) {
11338            if (needSep) pw.println();
11339            needSep = true;
11340            pw.println("  OOM levels:");
11341            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11342            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11343            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11344            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11345            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11346            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11347            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11348            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11349            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11350            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11351            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11352            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11353            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11354
11355            if (needSep) pw.println();
11356            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11357                    pw.print(" total, non-act at ");
11358                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11359                    pw.print(", non-svc at ");
11360                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11361                    pw.println("):");
11362            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11363            needSep = true;
11364        }
11365
11366        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11367
11368        pw.println();
11369        pw.println("  mHomeProcess: " + mHomeProcess);
11370        pw.println("  mPreviousProcess: " + mPreviousProcess);
11371        if (mHeavyWeightProcess != null) {
11372            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11373        }
11374
11375        return true;
11376    }
11377
11378    /**
11379     * There are three ways to call this:
11380     *  - no provider specified: dump all the providers
11381     *  - a flattened component name that matched an existing provider was specified as the
11382     *    first arg: dump that one provider
11383     *  - the first arg isn't the flattened component name of an existing provider:
11384     *    dump all providers whose component contains the first arg as a substring
11385     */
11386    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11387            int opti, boolean dumpAll) {
11388        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11389    }
11390
11391    static class ItemMatcher {
11392        ArrayList<ComponentName> components;
11393        ArrayList<String> strings;
11394        ArrayList<Integer> objects;
11395        boolean all;
11396
11397        ItemMatcher() {
11398            all = true;
11399        }
11400
11401        void build(String name) {
11402            ComponentName componentName = ComponentName.unflattenFromString(name);
11403            if (componentName != null) {
11404                if (components == null) {
11405                    components = new ArrayList<ComponentName>();
11406                }
11407                components.add(componentName);
11408                all = false;
11409            } else {
11410                int objectId = 0;
11411                // Not a '/' separated full component name; maybe an object ID?
11412                try {
11413                    objectId = Integer.parseInt(name, 16);
11414                    if (objects == null) {
11415                        objects = new ArrayList<Integer>();
11416                    }
11417                    objects.add(objectId);
11418                    all = false;
11419                } catch (RuntimeException e) {
11420                    // Not an integer; just do string match.
11421                    if (strings == null) {
11422                        strings = new ArrayList<String>();
11423                    }
11424                    strings.add(name);
11425                    all = false;
11426                }
11427            }
11428        }
11429
11430        int build(String[] args, int opti) {
11431            for (; opti<args.length; opti++) {
11432                String name = args[opti];
11433                if ("--".equals(name)) {
11434                    return opti+1;
11435                }
11436                build(name);
11437            }
11438            return opti;
11439        }
11440
11441        boolean match(Object object, ComponentName comp) {
11442            if (all) {
11443                return true;
11444            }
11445            if (components != null) {
11446                for (int i=0; i<components.size(); i++) {
11447                    if (components.get(i).equals(comp)) {
11448                        return true;
11449                    }
11450                }
11451            }
11452            if (objects != null) {
11453                for (int i=0; i<objects.size(); i++) {
11454                    if (System.identityHashCode(object) == objects.get(i)) {
11455                        return true;
11456                    }
11457                }
11458            }
11459            if (strings != null) {
11460                String flat = comp.flattenToString();
11461                for (int i=0; i<strings.size(); i++) {
11462                    if (flat.contains(strings.get(i))) {
11463                        return true;
11464                    }
11465                }
11466            }
11467            return false;
11468        }
11469    }
11470
11471    /**
11472     * There are three things that cmd can be:
11473     *  - a flattened component name that matches an existing activity
11474     *  - the cmd arg isn't the flattened component name of an existing activity:
11475     *    dump all activity whose component contains the cmd as a substring
11476     *  - A hex number of the ActivityRecord object instance.
11477     */
11478    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11479            int opti, boolean dumpAll) {
11480        ArrayList<ActivityRecord> activities;
11481
11482        synchronized (this) {
11483            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11484        }
11485
11486        if (activities.size() <= 0) {
11487            return false;
11488        }
11489
11490        String[] newArgs = new String[args.length - opti];
11491        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11492
11493        TaskRecord lastTask = null;
11494        boolean needSep = false;
11495        for (int i=activities.size()-1; i>=0; i--) {
11496            ActivityRecord r = activities.get(i);
11497            if (needSep) {
11498                pw.println();
11499            }
11500            needSep = true;
11501            synchronized (this) {
11502                if (lastTask != r.task) {
11503                    lastTask = r.task;
11504                    pw.print("TASK "); pw.print(lastTask.affinity);
11505                            pw.print(" id="); pw.println(lastTask.taskId);
11506                    if (dumpAll) {
11507                        lastTask.dump(pw, "  ");
11508                    }
11509                }
11510            }
11511            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11512        }
11513        return true;
11514    }
11515
11516    /**
11517     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11518     * there is a thread associated with the activity.
11519     */
11520    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11521            final ActivityRecord r, String[] args, boolean dumpAll) {
11522        String innerPrefix = prefix + "  ";
11523        synchronized (this) {
11524            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11525                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11526                    pw.print(" pid=");
11527                    if (r.app != null) pw.println(r.app.pid);
11528                    else pw.println("(not running)");
11529            if (dumpAll) {
11530                r.dump(pw, innerPrefix);
11531            }
11532        }
11533        if (r.app != null && r.app.thread != null) {
11534            // flush anything that is already in the PrintWriter since the thread is going
11535            // to write to the file descriptor directly
11536            pw.flush();
11537            try {
11538                TransferPipe tp = new TransferPipe();
11539                try {
11540                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11541                            r.appToken, innerPrefix, args);
11542                    tp.go(fd);
11543                } finally {
11544                    tp.kill();
11545                }
11546            } catch (IOException e) {
11547                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11548            } catch (RemoteException e) {
11549                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11550            }
11551        }
11552    }
11553
11554    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11555            int opti, boolean dumpAll, String dumpPackage) {
11556        boolean needSep = false;
11557        boolean onlyHistory = false;
11558        boolean printedAnything = false;
11559
11560        if ("history".equals(dumpPackage)) {
11561            if (opti < args.length && "-s".equals(args[opti])) {
11562                dumpAll = false;
11563            }
11564            onlyHistory = true;
11565            dumpPackage = null;
11566        }
11567
11568        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11569        if (!onlyHistory && dumpAll) {
11570            if (mRegisteredReceivers.size() > 0) {
11571                boolean printed = false;
11572                Iterator it = mRegisteredReceivers.values().iterator();
11573                while (it.hasNext()) {
11574                    ReceiverList r = (ReceiverList)it.next();
11575                    if (dumpPackage != null && (r.app == null ||
11576                            !dumpPackage.equals(r.app.info.packageName))) {
11577                        continue;
11578                    }
11579                    if (!printed) {
11580                        pw.println("  Registered Receivers:");
11581                        needSep = true;
11582                        printed = true;
11583                        printedAnything = true;
11584                    }
11585                    pw.print("  * "); pw.println(r);
11586                    r.dump(pw, "    ");
11587                }
11588            }
11589
11590            if (mReceiverResolver.dump(pw, needSep ?
11591                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11592                    "    ", dumpPackage, false)) {
11593                needSep = true;
11594                printedAnything = true;
11595            }
11596        }
11597
11598        for (BroadcastQueue q : mBroadcastQueues) {
11599            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11600            printedAnything |= needSep;
11601        }
11602
11603        needSep = true;
11604
11605        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11606            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11607                if (needSep) {
11608                    pw.println();
11609                }
11610                needSep = true;
11611                printedAnything = true;
11612                pw.print("  Sticky broadcasts for user ");
11613                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11614                StringBuilder sb = new StringBuilder(128);
11615                for (Map.Entry<String, ArrayList<Intent>> ent
11616                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11617                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11618                    if (dumpAll) {
11619                        pw.println(":");
11620                        ArrayList<Intent> intents = ent.getValue();
11621                        final int N = intents.size();
11622                        for (int i=0; i<N; i++) {
11623                            sb.setLength(0);
11624                            sb.append("    Intent: ");
11625                            intents.get(i).toShortString(sb, false, true, false, false);
11626                            pw.println(sb.toString());
11627                            Bundle bundle = intents.get(i).getExtras();
11628                            if (bundle != null) {
11629                                pw.print("      ");
11630                                pw.println(bundle.toString());
11631                            }
11632                        }
11633                    } else {
11634                        pw.println("");
11635                    }
11636                }
11637            }
11638        }
11639
11640        if (!onlyHistory && dumpAll) {
11641            pw.println();
11642            for (BroadcastQueue queue : mBroadcastQueues) {
11643                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11644                        + queue.mBroadcastsScheduled);
11645            }
11646            pw.println("  mHandler:");
11647            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11648            needSep = true;
11649            printedAnything = true;
11650        }
11651
11652        if (!printedAnything) {
11653            pw.println("  (nothing)");
11654        }
11655    }
11656
11657    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11658            int opti, boolean dumpAll, String dumpPackage) {
11659        boolean needSep;
11660        boolean printedAnything = false;
11661
11662        ItemMatcher matcher = new ItemMatcher();
11663        matcher.build(args, opti);
11664
11665        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11666
11667        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11668        printedAnything |= needSep;
11669
11670        if (mLaunchingProviders.size() > 0) {
11671            boolean printed = false;
11672            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11673                ContentProviderRecord r = mLaunchingProviders.get(i);
11674                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11675                    continue;
11676                }
11677                if (!printed) {
11678                    if (needSep) pw.println();
11679                    needSep = true;
11680                    pw.println("  Launching content providers:");
11681                    printed = true;
11682                    printedAnything = true;
11683                }
11684                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11685                        pw.println(r);
11686            }
11687        }
11688
11689        if (mGrantedUriPermissions.size() > 0) {
11690            boolean printed = false;
11691            int dumpUid = -2;
11692            if (dumpPackage != null) {
11693                try {
11694                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11695                } catch (NameNotFoundException e) {
11696                    dumpUid = -1;
11697                }
11698            }
11699            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11700                int uid = mGrantedUriPermissions.keyAt(i);
11701                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11702                    continue;
11703                }
11704                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11705                if (!printed) {
11706                    if (needSep) pw.println();
11707                    needSep = true;
11708                    pw.println("  Granted Uri Permissions:");
11709                    printed = true;
11710                    printedAnything = true;
11711                }
11712                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11713                for (UriPermission perm : perms.values()) {
11714                    pw.print("    "); pw.println(perm);
11715                    if (dumpAll) {
11716                        perm.dump(pw, "      ");
11717                    }
11718                }
11719            }
11720        }
11721
11722        if (!printedAnything) {
11723            pw.println("  (nothing)");
11724        }
11725    }
11726
11727    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11728            int opti, boolean dumpAll, String dumpPackage) {
11729        boolean printed = false;
11730
11731        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11732
11733        if (mIntentSenderRecords.size() > 0) {
11734            Iterator<WeakReference<PendingIntentRecord>> it
11735                    = mIntentSenderRecords.values().iterator();
11736            while (it.hasNext()) {
11737                WeakReference<PendingIntentRecord> ref = it.next();
11738                PendingIntentRecord rec = ref != null ? ref.get(): null;
11739                if (dumpPackage != null && (rec == null
11740                        || !dumpPackage.equals(rec.key.packageName))) {
11741                    continue;
11742                }
11743                printed = true;
11744                if (rec != null) {
11745                    pw.print("  * "); pw.println(rec);
11746                    if (dumpAll) {
11747                        rec.dump(pw, "    ");
11748                    }
11749                } else {
11750                    pw.print("  * "); pw.println(ref);
11751                }
11752            }
11753        }
11754
11755        if (!printed) {
11756            pw.println("  (nothing)");
11757        }
11758    }
11759
11760    private static final int dumpProcessList(PrintWriter pw,
11761            ActivityManagerService service, List list,
11762            String prefix, String normalLabel, String persistentLabel,
11763            String dumpPackage) {
11764        int numPers = 0;
11765        final int N = list.size()-1;
11766        for (int i=N; i>=0; i--) {
11767            ProcessRecord r = (ProcessRecord)list.get(i);
11768            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11769                continue;
11770            }
11771            pw.println(String.format("%s%s #%2d: %s",
11772                    prefix, (r.persistent ? persistentLabel : normalLabel),
11773                    i, r.toString()));
11774            if (r.persistent) {
11775                numPers++;
11776            }
11777        }
11778        return numPers;
11779    }
11780
11781    private static final boolean dumpProcessOomList(PrintWriter pw,
11782            ActivityManagerService service, List<ProcessRecord> origList,
11783            String prefix, String normalLabel, String persistentLabel,
11784            boolean inclDetails, String dumpPackage) {
11785
11786        ArrayList<Pair<ProcessRecord, Integer>> list
11787                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11788        for (int i=0; i<origList.size(); i++) {
11789            ProcessRecord r = origList.get(i);
11790            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11791                continue;
11792            }
11793            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11794        }
11795
11796        if (list.size() <= 0) {
11797            return false;
11798        }
11799
11800        Comparator<Pair<ProcessRecord, Integer>> comparator
11801                = new Comparator<Pair<ProcessRecord, Integer>>() {
11802            @Override
11803            public int compare(Pair<ProcessRecord, Integer> object1,
11804                    Pair<ProcessRecord, Integer> object2) {
11805                if (object1.first.setAdj != object2.first.setAdj) {
11806                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11807                }
11808                if (object1.second.intValue() != object2.second.intValue()) {
11809                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11810                }
11811                return 0;
11812            }
11813        };
11814
11815        Collections.sort(list, comparator);
11816
11817        final long curRealtime = SystemClock.elapsedRealtime();
11818        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11819        final long curUptime = SystemClock.uptimeMillis();
11820        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11821
11822        for (int i=list.size()-1; i>=0; i--) {
11823            ProcessRecord r = list.get(i).first;
11824            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11825            char schedGroup;
11826            switch (r.setSchedGroup) {
11827                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11828                    schedGroup = 'B';
11829                    break;
11830                case Process.THREAD_GROUP_DEFAULT:
11831                    schedGroup = 'F';
11832                    break;
11833                default:
11834                    schedGroup = '?';
11835                    break;
11836            }
11837            char foreground;
11838            if (r.foregroundActivities) {
11839                foreground = 'A';
11840            } else if (r.foregroundServices) {
11841                foreground = 'S';
11842            } else {
11843                foreground = ' ';
11844            }
11845            String procState = ProcessList.makeProcStateString(r.curProcState);
11846            pw.print(prefix);
11847            pw.print(r.persistent ? persistentLabel : normalLabel);
11848            pw.print(" #");
11849            int num = (origList.size()-1)-list.get(i).second;
11850            if (num < 10) pw.print(' ');
11851            pw.print(num);
11852            pw.print(": ");
11853            pw.print(oomAdj);
11854            pw.print(' ');
11855            pw.print(schedGroup);
11856            pw.print('/');
11857            pw.print(foreground);
11858            pw.print('/');
11859            pw.print(procState);
11860            pw.print(" trm:");
11861            if (r.trimMemoryLevel < 10) pw.print(' ');
11862            pw.print(r.trimMemoryLevel);
11863            pw.print(' ');
11864            pw.print(r.toShortString());
11865            pw.print(" (");
11866            pw.print(r.adjType);
11867            pw.println(')');
11868            if (r.adjSource != null || r.adjTarget != null) {
11869                pw.print(prefix);
11870                pw.print("    ");
11871                if (r.adjTarget instanceof ComponentName) {
11872                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11873                } else if (r.adjTarget != null) {
11874                    pw.print(r.adjTarget.toString());
11875                } else {
11876                    pw.print("{null}");
11877                }
11878                pw.print("<=");
11879                if (r.adjSource instanceof ProcessRecord) {
11880                    pw.print("Proc{");
11881                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11882                    pw.println("}");
11883                } else if (r.adjSource != null) {
11884                    pw.println(r.adjSource.toString());
11885                } else {
11886                    pw.println("{null}");
11887                }
11888            }
11889            if (inclDetails) {
11890                pw.print(prefix);
11891                pw.print("    ");
11892                pw.print("oom: max="); pw.print(r.maxAdj);
11893                pw.print(" curRaw="); pw.print(r.curRawAdj);
11894                pw.print(" setRaw="); pw.print(r.setRawAdj);
11895                pw.print(" cur="); pw.print(r.curAdj);
11896                pw.print(" set="); pw.println(r.setAdj);
11897                pw.print(prefix);
11898                pw.print("    ");
11899                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11900                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11901                pw.print(" lastPss="); pw.print(r.lastPss);
11902                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11903                pw.print(prefix);
11904                pw.print("    ");
11905                pw.print("keeping="); pw.print(r.keeping);
11906                pw.print(" cached="); pw.print(r.cached);
11907                pw.print(" empty="); pw.print(r.empty);
11908                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11909
11910                if (!r.keeping) {
11911                    if (r.lastWakeTime != 0) {
11912                        long wtime;
11913                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11914                        synchronized (stats) {
11915                            wtime = stats.getProcessWakeTime(r.info.uid,
11916                                    r.pid, curRealtime);
11917                        }
11918                        long timeUsed = wtime - r.lastWakeTime;
11919                        pw.print(prefix);
11920                        pw.print("    ");
11921                        pw.print("keep awake over ");
11922                        TimeUtils.formatDuration(realtimeSince, pw);
11923                        pw.print(" used ");
11924                        TimeUtils.formatDuration(timeUsed, pw);
11925                        pw.print(" (");
11926                        pw.print((timeUsed*100)/realtimeSince);
11927                        pw.println("%)");
11928                    }
11929                    if (r.lastCpuTime != 0) {
11930                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11931                        pw.print(prefix);
11932                        pw.print("    ");
11933                        pw.print("run cpu over ");
11934                        TimeUtils.formatDuration(uptimeSince, pw);
11935                        pw.print(" used ");
11936                        TimeUtils.formatDuration(timeUsed, pw);
11937                        pw.print(" (");
11938                        pw.print((timeUsed*100)/uptimeSince);
11939                        pw.println("%)");
11940                    }
11941                }
11942            }
11943        }
11944        return true;
11945    }
11946
11947    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11948        ArrayList<ProcessRecord> procs;
11949        synchronized (this) {
11950            if (args != null && args.length > start
11951                    && args[start].charAt(0) != '-') {
11952                procs = new ArrayList<ProcessRecord>();
11953                int pid = -1;
11954                try {
11955                    pid = Integer.parseInt(args[start]);
11956                } catch (NumberFormatException e) {
11957                }
11958                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11959                    ProcessRecord proc = mLruProcesses.get(i);
11960                    if (proc.pid == pid) {
11961                        procs.add(proc);
11962                    } else if (proc.processName.equals(args[start])) {
11963                        procs.add(proc);
11964                    }
11965                }
11966                if (procs.size() <= 0) {
11967                    return null;
11968                }
11969            } else {
11970                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11971            }
11972        }
11973        return procs;
11974    }
11975
11976    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11977            PrintWriter pw, String[] args) {
11978        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11979        if (procs == null) {
11980            pw.println("No process found for: " + args[0]);
11981            return;
11982        }
11983
11984        long uptime = SystemClock.uptimeMillis();
11985        long realtime = SystemClock.elapsedRealtime();
11986        pw.println("Applications Graphics Acceleration Info:");
11987        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11988
11989        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11990            ProcessRecord r = procs.get(i);
11991            if (r.thread != null) {
11992                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11993                pw.flush();
11994                try {
11995                    TransferPipe tp = new TransferPipe();
11996                    try {
11997                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11998                        tp.go(fd);
11999                    } finally {
12000                        tp.kill();
12001                    }
12002                } catch (IOException e) {
12003                    pw.println("Failure while dumping the app: " + r);
12004                    pw.flush();
12005                } catch (RemoteException e) {
12006                    pw.println("Got a RemoteException while dumping the app " + r);
12007                    pw.flush();
12008                }
12009            }
12010        }
12011    }
12012
12013    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12014        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12015        if (procs == null) {
12016            pw.println("No process found for: " + args[0]);
12017            return;
12018        }
12019
12020        pw.println("Applications Database Info:");
12021
12022        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12023            ProcessRecord r = procs.get(i);
12024            if (r.thread != null) {
12025                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12026                pw.flush();
12027                try {
12028                    TransferPipe tp = new TransferPipe();
12029                    try {
12030                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12031                        tp.go(fd);
12032                    } finally {
12033                        tp.kill();
12034                    }
12035                } catch (IOException e) {
12036                    pw.println("Failure while dumping the app: " + r);
12037                    pw.flush();
12038                } catch (RemoteException e) {
12039                    pw.println("Got a RemoteException while dumping the app " + r);
12040                    pw.flush();
12041                }
12042            }
12043        }
12044    }
12045
12046    final static class MemItem {
12047        final boolean isProc;
12048        final String label;
12049        final String shortLabel;
12050        final long pss;
12051        final int id;
12052        final boolean hasActivities;
12053        ArrayList<MemItem> subitems;
12054
12055        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12056                boolean _hasActivities) {
12057            isProc = true;
12058            label = _label;
12059            shortLabel = _shortLabel;
12060            pss = _pss;
12061            id = _id;
12062            hasActivities = _hasActivities;
12063        }
12064
12065        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12066            isProc = false;
12067            label = _label;
12068            shortLabel = _shortLabel;
12069            pss = _pss;
12070            id = _id;
12071            hasActivities = false;
12072        }
12073    }
12074
12075    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12076            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12077        if (sort && !isCompact) {
12078            Collections.sort(items, new Comparator<MemItem>() {
12079                @Override
12080                public int compare(MemItem lhs, MemItem rhs) {
12081                    if (lhs.pss < rhs.pss) {
12082                        return 1;
12083                    } else if (lhs.pss > rhs.pss) {
12084                        return -1;
12085                    }
12086                    return 0;
12087                }
12088            });
12089        }
12090
12091        for (int i=0; i<items.size(); i++) {
12092            MemItem mi = items.get(i);
12093            if (!isCompact) {
12094                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12095            } else if (mi.isProc) {
12096                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12097                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12098                pw.println(mi.hasActivities ? ",a" : ",e");
12099            } else {
12100                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12101                pw.println(mi.pss);
12102            }
12103            if (mi.subitems != null) {
12104                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12105                        true, isCompact);
12106            }
12107        }
12108    }
12109
12110    // These are in KB.
12111    static final long[] DUMP_MEM_BUCKETS = new long[] {
12112        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12113        120*1024, 160*1024, 200*1024,
12114        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12115        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12116    };
12117
12118    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12119            boolean stackLike) {
12120        int start = label.lastIndexOf('.');
12121        if (start >= 0) start++;
12122        else start = 0;
12123        int end = label.length();
12124        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12125            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12126                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12127                out.append(bucket);
12128                out.append(stackLike ? "MB." : "MB ");
12129                out.append(label, start, end);
12130                return;
12131            }
12132        }
12133        out.append(memKB/1024);
12134        out.append(stackLike ? "MB." : "MB ");
12135        out.append(label, start, end);
12136    }
12137
12138    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12139            ProcessList.NATIVE_ADJ,
12140            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12141            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12142            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12143            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12144            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12145    };
12146    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12147            "Native",
12148            "System", "Persistent", "Foreground",
12149            "Visible", "Perceptible",
12150            "Heavy Weight", "Backup",
12151            "A Services", "Home",
12152            "Previous", "B Services", "Cached"
12153    };
12154    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12155            "native",
12156            "sys", "pers", "fore",
12157            "vis", "percept",
12158            "heavy", "backup",
12159            "servicea", "home",
12160            "prev", "serviceb", "cached"
12161    };
12162
12163    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12164            long realtime, boolean isCheckinRequest, boolean isCompact) {
12165        if (isCheckinRequest || isCompact) {
12166            // short checkin version
12167            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12168        } else {
12169            pw.println("Applications Memory Usage (kB):");
12170            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12171        }
12172    }
12173
12174    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12175            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12176        boolean dumpDetails = false;
12177        boolean dumpFullDetails = false;
12178        boolean dumpDalvik = false;
12179        boolean oomOnly = false;
12180        boolean isCompact = false;
12181        boolean localOnly = false;
12182
12183        int opti = 0;
12184        while (opti < args.length) {
12185            String opt = args[opti];
12186            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12187                break;
12188            }
12189            opti++;
12190            if ("-a".equals(opt)) {
12191                dumpDetails = true;
12192                dumpFullDetails = true;
12193                dumpDalvik = true;
12194            } else if ("-d".equals(opt)) {
12195                dumpDalvik = true;
12196            } else if ("-c".equals(opt)) {
12197                isCompact = true;
12198            } else if ("--oom".equals(opt)) {
12199                oomOnly = true;
12200            } else if ("--local".equals(opt)) {
12201                localOnly = true;
12202            } else if ("-h".equals(opt)) {
12203                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12204                pw.println("  -a: include all available information for each process.");
12205                pw.println("  -d: include dalvik details when dumping process details.");
12206                pw.println("  -c: dump in a compact machine-parseable representation.");
12207                pw.println("  --oom: only show processes organized by oom adj.");
12208                pw.println("  --local: only collect details locally, don't call process.");
12209                pw.println("If [process] is specified it can be the name or ");
12210                pw.println("pid of a specific process to dump.");
12211                return;
12212            } else {
12213                pw.println("Unknown argument: " + opt + "; use -h for help");
12214            }
12215        }
12216
12217        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12218        long uptime = SystemClock.uptimeMillis();
12219        long realtime = SystemClock.elapsedRealtime();
12220        final long[] tmpLong = new long[1];
12221
12222        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12223        if (procs == null) {
12224            // No Java processes.  Maybe they want to print a native process.
12225            if (args != null && args.length > opti
12226                    && args[opti].charAt(0) != '-') {
12227                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12228                        = new ArrayList<ProcessCpuTracker.Stats>();
12229                updateCpuStatsNow();
12230                int findPid = -1;
12231                try {
12232                    findPid = Integer.parseInt(args[opti]);
12233                } catch (NumberFormatException e) {
12234                }
12235                synchronized (mProcessCpuThread) {
12236                    final int N = mProcessCpuTracker.countStats();
12237                    for (int i=0; i<N; i++) {
12238                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12239                        if (st.pid == findPid || (st.baseName != null
12240                                && st.baseName.equals(args[opti]))) {
12241                            nativeProcs.add(st);
12242                        }
12243                    }
12244                }
12245                if (nativeProcs.size() > 0) {
12246                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12247                            isCompact);
12248                    Debug.MemoryInfo mi = null;
12249                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12250                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12251                        final int pid = r.pid;
12252                        if (!isCheckinRequest && dumpDetails) {
12253                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12254                        }
12255                        if (mi == null) {
12256                            mi = new Debug.MemoryInfo();
12257                        }
12258                        if (dumpDetails || (!brief && !oomOnly)) {
12259                            Debug.getMemoryInfo(pid, mi);
12260                        } else {
12261                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12262                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12263                        }
12264                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12265                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12266                        if (isCheckinRequest) {
12267                            pw.println();
12268                        }
12269                    }
12270                    return;
12271                }
12272            }
12273            pw.println("No process found for: " + args[opti]);
12274            return;
12275        }
12276
12277        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12278            dumpDetails = true;
12279        }
12280
12281        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12282
12283        String[] innerArgs = new String[args.length-opti];
12284        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12285
12286        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12287        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12288        long nativePss=0, dalvikPss=0, otherPss=0;
12289        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12290
12291        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12292        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12293                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12294
12295        long totalPss = 0;
12296        long cachedPss = 0;
12297
12298        Debug.MemoryInfo mi = null;
12299        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12300            final ProcessRecord r = procs.get(i);
12301            final IApplicationThread thread;
12302            final int pid;
12303            final int oomAdj;
12304            final boolean hasActivities;
12305            synchronized (this) {
12306                thread = r.thread;
12307                pid = r.pid;
12308                oomAdj = r.getSetAdjWithServices();
12309                hasActivities = r.activities.size() > 0;
12310            }
12311            if (thread != null) {
12312                if (!isCheckinRequest && dumpDetails) {
12313                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12314                }
12315                if (mi == null) {
12316                    mi = new Debug.MemoryInfo();
12317                }
12318                if (dumpDetails || (!brief && !oomOnly)) {
12319                    Debug.getMemoryInfo(pid, mi);
12320                } else {
12321                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12322                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12323                }
12324                if (dumpDetails) {
12325                    if (localOnly) {
12326                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12327                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12328                        if (isCheckinRequest) {
12329                            pw.println();
12330                        }
12331                    } else {
12332                        try {
12333                            pw.flush();
12334                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12335                                    dumpDalvik, innerArgs);
12336                        } catch (RemoteException e) {
12337                            if (!isCheckinRequest) {
12338                                pw.println("Got RemoteException!");
12339                                pw.flush();
12340                            }
12341                        }
12342                    }
12343                }
12344
12345                final long myTotalPss = mi.getTotalPss();
12346                final long myTotalUss = mi.getTotalUss();
12347
12348                synchronized (this) {
12349                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12350                        // Record this for posterity if the process has been stable.
12351                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12352                    }
12353                }
12354
12355                if (!isCheckinRequest && mi != null) {
12356                    totalPss += myTotalPss;
12357                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12358                            (hasActivities ? " / activities)" : ")"),
12359                            r.processName, myTotalPss, pid, hasActivities);
12360                    procMems.add(pssItem);
12361                    procMemsMap.put(pid, pssItem);
12362
12363                    nativePss += mi.nativePss;
12364                    dalvikPss += mi.dalvikPss;
12365                    otherPss += mi.otherPss;
12366                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12367                        long mem = mi.getOtherPss(j);
12368                        miscPss[j] += mem;
12369                        otherPss -= mem;
12370                    }
12371
12372                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12373                        cachedPss += myTotalPss;
12374                    }
12375
12376                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12377                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12378                                || oomIndex == (oomPss.length-1)) {
12379                            oomPss[oomIndex] += myTotalPss;
12380                            if (oomProcs[oomIndex] == null) {
12381                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12382                            }
12383                            oomProcs[oomIndex].add(pssItem);
12384                            break;
12385                        }
12386                    }
12387                }
12388            }
12389        }
12390
12391        if (!isCheckinRequest && procs.size() > 1) {
12392            // If we are showing aggregations, also look for native processes to
12393            // include so that our aggregations are more accurate.
12394            updateCpuStatsNow();
12395            synchronized (mProcessCpuThread) {
12396                final int N = mProcessCpuTracker.countStats();
12397                for (int i=0; i<N; i++) {
12398                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12399                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12400                        if (mi == null) {
12401                            mi = new Debug.MemoryInfo();
12402                        }
12403                        if (!brief && !oomOnly) {
12404                            Debug.getMemoryInfo(st.pid, mi);
12405                        } else {
12406                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12407                            mi.nativePrivateDirty = (int)tmpLong[0];
12408                        }
12409
12410                        final long myTotalPss = mi.getTotalPss();
12411                        totalPss += myTotalPss;
12412
12413                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12414                                st.name, myTotalPss, st.pid, false);
12415                        procMems.add(pssItem);
12416
12417                        nativePss += mi.nativePss;
12418                        dalvikPss += mi.dalvikPss;
12419                        otherPss += mi.otherPss;
12420                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12421                            long mem = mi.getOtherPss(j);
12422                            miscPss[j] += mem;
12423                            otherPss -= mem;
12424                        }
12425                        oomPss[0] += myTotalPss;
12426                        if (oomProcs[0] == null) {
12427                            oomProcs[0] = new ArrayList<MemItem>();
12428                        }
12429                        oomProcs[0].add(pssItem);
12430                    }
12431                }
12432            }
12433
12434            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12435
12436            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12437            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12438            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12439            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12440                String label = Debug.MemoryInfo.getOtherLabel(j);
12441                catMems.add(new MemItem(label, label, miscPss[j], j));
12442            }
12443
12444            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12445            for (int j=0; j<oomPss.length; j++) {
12446                if (oomPss[j] != 0) {
12447                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12448                            : DUMP_MEM_OOM_LABEL[j];
12449                    MemItem item = new MemItem(label, label, oomPss[j],
12450                            DUMP_MEM_OOM_ADJ[j]);
12451                    item.subitems = oomProcs[j];
12452                    oomMems.add(item);
12453                }
12454            }
12455
12456            if (!brief && !oomOnly && !isCompact) {
12457                pw.println();
12458                pw.println("Total PSS by process:");
12459                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12460                pw.println();
12461            }
12462            if (!isCompact) {
12463                pw.println("Total PSS by OOM adjustment:");
12464            }
12465            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12466            if (!brief && !oomOnly) {
12467                PrintWriter out = categoryPw != null ? categoryPw : pw;
12468                if (!isCompact) {
12469                    out.println();
12470                    out.println("Total PSS by category:");
12471                }
12472                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12473            }
12474            if (!isCompact) {
12475                pw.println();
12476            }
12477            MemInfoReader memInfo = new MemInfoReader();
12478            memInfo.readMemInfo();
12479            if (!brief) {
12480                if (!isCompact) {
12481                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12482                    pw.print(" kB (status ");
12483                    switch (mLastMemoryLevel) {
12484                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12485                            pw.println("normal)");
12486                            break;
12487                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12488                            pw.println("moderate)");
12489                            break;
12490                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12491                            pw.println("low)");
12492                            break;
12493                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12494                            pw.println("critical)");
12495                            break;
12496                        default:
12497                            pw.print(mLastMemoryLevel);
12498                            pw.println(")");
12499                            break;
12500                    }
12501                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12502                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12503                            pw.print(cachedPss); pw.print(" cached pss + ");
12504                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12505                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12506                } else {
12507                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12508                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12509                            + memInfo.getFreeSizeKb()); pw.print(",");
12510                    pw.println(totalPss - cachedPss);
12511                }
12512            }
12513            if (!isCompact) {
12514                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12515                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12516                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12517                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12518                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12519                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12520                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12521                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12522                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12523                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12524                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12525            }
12526            if (!brief) {
12527                if (memInfo.getZramTotalSizeKb() != 0) {
12528                    if (!isCompact) {
12529                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12530                                pw.print(" kB physical used for ");
12531                                pw.print(memInfo.getSwapTotalSizeKb()
12532                                        - memInfo.getSwapFreeSizeKb());
12533                                pw.print(" kB in swap (");
12534                                pw.print(memInfo.getSwapTotalSizeKb());
12535                                pw.println(" kB total swap)");
12536                    } else {
12537                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12538                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12539                                pw.println(memInfo.getSwapFreeSizeKb());
12540                    }
12541                }
12542                final int[] SINGLE_LONG_FORMAT = new int[] {
12543                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12544                };
12545                long[] longOut = new long[1];
12546                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12547                        SINGLE_LONG_FORMAT, null, longOut, null);
12548                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12549                longOut[0] = 0;
12550                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12551                        SINGLE_LONG_FORMAT, null, longOut, null);
12552                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12553                longOut[0] = 0;
12554                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12555                        SINGLE_LONG_FORMAT, null, longOut, null);
12556                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12557                longOut[0] = 0;
12558                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12559                        SINGLE_LONG_FORMAT, null, longOut, null);
12560                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12561                if (!isCompact) {
12562                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12563                        pw.print("      KSM: "); pw.print(sharing);
12564                                pw.print(" kB saved from shared ");
12565                                pw.print(shared); pw.println(" kB");
12566                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12567                                pw.print(voltile); pw.println(" kB volatile");
12568                    }
12569                    pw.print("   Tuning: ");
12570                    pw.print(ActivityManager.staticGetMemoryClass());
12571                    pw.print(" (large ");
12572                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12573                    pw.print("), oom ");
12574                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12575                    pw.print(" kB");
12576                    pw.print(", restore limit ");
12577                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12578                    pw.print(" kB");
12579                    if (ActivityManager.isLowRamDeviceStatic()) {
12580                        pw.print(" (low-ram)");
12581                    }
12582                    if (ActivityManager.isHighEndGfx()) {
12583                        pw.print(" (high-end-gfx)");
12584                    }
12585                    pw.println();
12586                } else {
12587                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12588                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12589                    pw.println(voltile);
12590                    pw.print("tuning,");
12591                    pw.print(ActivityManager.staticGetMemoryClass());
12592                    pw.print(',');
12593                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12594                    pw.print(',');
12595                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12596                    if (ActivityManager.isLowRamDeviceStatic()) {
12597                        pw.print(",low-ram");
12598                    }
12599                    if (ActivityManager.isHighEndGfx()) {
12600                        pw.print(",high-end-gfx");
12601                    }
12602                    pw.println();
12603                }
12604            }
12605        }
12606    }
12607
12608    /**
12609     * Searches array of arguments for the specified string
12610     * @param args array of argument strings
12611     * @param value value to search for
12612     * @return true if the value is contained in the array
12613     */
12614    private static boolean scanArgs(String[] args, String value) {
12615        if (args != null) {
12616            for (String arg : args) {
12617                if (value.equals(arg)) {
12618                    return true;
12619                }
12620            }
12621        }
12622        return false;
12623    }
12624
12625    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12626            ContentProviderRecord cpr, boolean always) {
12627        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12628
12629        if (!inLaunching || always) {
12630            synchronized (cpr) {
12631                cpr.launchingApp = null;
12632                cpr.notifyAll();
12633            }
12634            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12635            String names[] = cpr.info.authority.split(";");
12636            for (int j = 0; j < names.length; j++) {
12637                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12638            }
12639        }
12640
12641        for (int i=0; i<cpr.connections.size(); i++) {
12642            ContentProviderConnection conn = cpr.connections.get(i);
12643            if (conn.waiting) {
12644                // If this connection is waiting for the provider, then we don't
12645                // need to mess with its process unless we are always removing
12646                // or for some reason the provider is not currently launching.
12647                if (inLaunching && !always) {
12648                    continue;
12649                }
12650            }
12651            ProcessRecord capp = conn.client;
12652            conn.dead = true;
12653            if (conn.stableCount > 0) {
12654                if (!capp.persistent && capp.thread != null
12655                        && capp.pid != 0
12656                        && capp.pid != MY_PID) {
12657                    killUnneededProcessLocked(capp, "depends on provider "
12658                            + cpr.name.flattenToShortString()
12659                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12660                }
12661            } else if (capp.thread != null && conn.provider.provider != null) {
12662                try {
12663                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12664                } catch (RemoteException e) {
12665                }
12666                // In the protocol here, we don't expect the client to correctly
12667                // clean up this connection, we'll just remove it.
12668                cpr.connections.remove(i);
12669                conn.client.conProviders.remove(conn);
12670            }
12671        }
12672
12673        if (inLaunching && always) {
12674            mLaunchingProviders.remove(cpr);
12675        }
12676        return inLaunching;
12677    }
12678
12679    /**
12680     * Main code for cleaning up a process when it has gone away.  This is
12681     * called both as a result of the process dying, or directly when stopping
12682     * a process when running in single process mode.
12683     */
12684    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12685            boolean restarting, boolean allowRestart, int index) {
12686        if (index >= 0) {
12687            removeLruProcessLocked(app);
12688            ProcessList.remove(app.pid);
12689        }
12690
12691        mProcessesToGc.remove(app);
12692        mPendingPssProcesses.remove(app);
12693
12694        // Dismiss any open dialogs.
12695        if (app.crashDialog != null && !app.forceCrashReport) {
12696            app.crashDialog.dismiss();
12697            app.crashDialog = null;
12698        }
12699        if (app.anrDialog != null) {
12700            app.anrDialog.dismiss();
12701            app.anrDialog = null;
12702        }
12703        if (app.waitDialog != null) {
12704            app.waitDialog.dismiss();
12705            app.waitDialog = null;
12706        }
12707
12708        app.crashing = false;
12709        app.notResponding = false;
12710
12711        app.resetPackageList(mProcessStats);
12712        app.unlinkDeathRecipient();
12713        app.makeInactive(mProcessStats);
12714        app.forcingToForeground = null;
12715        updateProcessForegroundLocked(app, false, false);
12716        app.foregroundActivities = false;
12717        app.hasShownUi = false;
12718        app.treatLikeActivity = false;
12719        app.hasAboveClient = false;
12720        app.hasClientActivities = false;
12721
12722        mServices.killServicesLocked(app, allowRestart);
12723
12724        boolean restart = false;
12725
12726        // Remove published content providers.
12727        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12728            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12729            final boolean always = app.bad || !allowRestart;
12730            if (removeDyingProviderLocked(app, cpr, always) || always) {
12731                // We left the provider in the launching list, need to
12732                // restart it.
12733                restart = true;
12734            }
12735
12736            cpr.provider = null;
12737            cpr.proc = null;
12738        }
12739        app.pubProviders.clear();
12740
12741        // Take care of any launching providers waiting for this process.
12742        if (checkAppInLaunchingProvidersLocked(app, false)) {
12743            restart = true;
12744        }
12745
12746        // Unregister from connected content providers.
12747        if (!app.conProviders.isEmpty()) {
12748            for (int i=0; i<app.conProviders.size(); i++) {
12749                ContentProviderConnection conn = app.conProviders.get(i);
12750                conn.provider.connections.remove(conn);
12751            }
12752            app.conProviders.clear();
12753        }
12754
12755        // At this point there may be remaining entries in mLaunchingProviders
12756        // where we were the only one waiting, so they are no longer of use.
12757        // Look for these and clean up if found.
12758        // XXX Commented out for now.  Trying to figure out a way to reproduce
12759        // the actual situation to identify what is actually going on.
12760        if (false) {
12761            for (int i=0; i<mLaunchingProviders.size(); i++) {
12762                ContentProviderRecord cpr = (ContentProviderRecord)
12763                        mLaunchingProviders.get(i);
12764                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12765                    synchronized (cpr) {
12766                        cpr.launchingApp = null;
12767                        cpr.notifyAll();
12768                    }
12769                }
12770            }
12771        }
12772
12773        skipCurrentReceiverLocked(app);
12774
12775        // Unregister any receivers.
12776        for (int i=app.receivers.size()-1; i>=0; i--) {
12777            removeReceiverLocked(app.receivers.valueAt(i));
12778        }
12779        app.receivers.clear();
12780
12781        // If the app is undergoing backup, tell the backup manager about it
12782        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12783            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12784                    + mBackupTarget.appInfo + " died during backup");
12785            try {
12786                IBackupManager bm = IBackupManager.Stub.asInterface(
12787                        ServiceManager.getService(Context.BACKUP_SERVICE));
12788                bm.agentDisconnected(app.info.packageName);
12789            } catch (RemoteException e) {
12790                // can't happen; backup manager is local
12791            }
12792        }
12793
12794        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12795            ProcessChangeItem item = mPendingProcessChanges.get(i);
12796            if (item.pid == app.pid) {
12797                mPendingProcessChanges.remove(i);
12798                mAvailProcessChanges.add(item);
12799            }
12800        }
12801        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12802
12803        // If the caller is restarting this app, then leave it in its
12804        // current lists and let the caller take care of it.
12805        if (restarting) {
12806            return;
12807        }
12808
12809        if (!app.persistent || app.isolated) {
12810            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12811                    "Removing non-persistent process during cleanup: " + app);
12812            mProcessNames.remove(app.processName, app.uid);
12813            mIsolatedProcesses.remove(app.uid);
12814            if (mHeavyWeightProcess == app) {
12815                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12816                        mHeavyWeightProcess.userId, 0));
12817                mHeavyWeightProcess = null;
12818            }
12819        } else if (!app.removed) {
12820            // This app is persistent, so we need to keep its record around.
12821            // If it is not already on the pending app list, add it there
12822            // and start a new process for it.
12823            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12824                mPersistentStartingProcesses.add(app);
12825                restart = true;
12826            }
12827        }
12828        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12829                "Clean-up removing on hold: " + app);
12830        mProcessesOnHold.remove(app);
12831
12832        if (app == mHomeProcess) {
12833            mHomeProcess = null;
12834        }
12835        if (app == mPreviousProcess) {
12836            mPreviousProcess = null;
12837        }
12838
12839        if (restart && !app.isolated) {
12840            // We have components that still need to be running in the
12841            // process, so re-launch it.
12842            mProcessNames.put(app.processName, app.uid, app);
12843            startProcessLocked(app, "restart", app.processName);
12844        } else if (app.pid > 0 && app.pid != MY_PID) {
12845            // Goodbye!
12846            boolean removed;
12847            synchronized (mPidsSelfLocked) {
12848                mPidsSelfLocked.remove(app.pid);
12849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12850            }
12851            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12852                    app.processName, app.info.uid);
12853            if (app.isolated) {
12854                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12855            }
12856            app.setPid(0);
12857        }
12858    }
12859
12860    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12861        // Look through the content providers we are waiting to have launched,
12862        // and if any run in this process then either schedule a restart of
12863        // the process or kill the client waiting for it if this process has
12864        // gone bad.
12865        int NL = mLaunchingProviders.size();
12866        boolean restart = false;
12867        for (int i=0; i<NL; i++) {
12868            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12869            if (cpr.launchingApp == app) {
12870                if (!alwaysBad && !app.bad) {
12871                    restart = true;
12872                } else {
12873                    removeDyingProviderLocked(app, cpr, true);
12874                    // cpr should have been removed from mLaunchingProviders
12875                    NL = mLaunchingProviders.size();
12876                    i--;
12877                }
12878            }
12879        }
12880        return restart;
12881    }
12882
12883    // =========================================================
12884    // SERVICES
12885    // =========================================================
12886
12887    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12888            int flags) {
12889        enforceNotIsolatedCaller("getServices");
12890        synchronized (this) {
12891            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12892        }
12893    }
12894
12895    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12896        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12897        synchronized (this) {
12898            return mServices.getRunningServiceControlPanelLocked(name);
12899        }
12900    }
12901
12902    public ComponentName startService(IApplicationThread caller, Intent service,
12903            String resolvedType, int userId) {
12904        enforceNotIsolatedCaller("startService");
12905        // Refuse possible leaked file descriptors
12906        if (service != null && service.hasFileDescriptors() == true) {
12907            throw new IllegalArgumentException("File descriptors passed in Intent");
12908        }
12909
12910        if (DEBUG_SERVICE)
12911            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12912        synchronized(this) {
12913            final int callingPid = Binder.getCallingPid();
12914            final int callingUid = Binder.getCallingUid();
12915            final long origId = Binder.clearCallingIdentity();
12916            ComponentName res = mServices.startServiceLocked(caller, service,
12917                    resolvedType, callingPid, callingUid, userId);
12918            Binder.restoreCallingIdentity(origId);
12919            return res;
12920        }
12921    }
12922
12923    ComponentName startServiceInPackage(int uid,
12924            Intent service, String resolvedType, int userId) {
12925        synchronized(this) {
12926            if (DEBUG_SERVICE)
12927                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12928            final long origId = Binder.clearCallingIdentity();
12929            ComponentName res = mServices.startServiceLocked(null, service,
12930                    resolvedType, -1, uid, userId);
12931            Binder.restoreCallingIdentity(origId);
12932            return res;
12933        }
12934    }
12935
12936    public int stopService(IApplicationThread caller, Intent service,
12937            String resolvedType, int userId) {
12938        enforceNotIsolatedCaller("stopService");
12939        // Refuse possible leaked file descriptors
12940        if (service != null && service.hasFileDescriptors() == true) {
12941            throw new IllegalArgumentException("File descriptors passed in Intent");
12942        }
12943
12944        synchronized(this) {
12945            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12946        }
12947    }
12948
12949    public IBinder peekService(Intent service, String resolvedType) {
12950        enforceNotIsolatedCaller("peekService");
12951        // Refuse possible leaked file descriptors
12952        if (service != null && service.hasFileDescriptors() == true) {
12953            throw new IllegalArgumentException("File descriptors passed in Intent");
12954        }
12955        synchronized(this) {
12956            return mServices.peekServiceLocked(service, resolvedType);
12957        }
12958    }
12959
12960    public boolean stopServiceToken(ComponentName className, IBinder token,
12961            int startId) {
12962        synchronized(this) {
12963            return mServices.stopServiceTokenLocked(className, token, startId);
12964        }
12965    }
12966
12967    public void setServiceForeground(ComponentName className, IBinder token,
12968            int id, Notification notification, boolean removeNotification) {
12969        synchronized(this) {
12970            mServices.setServiceForegroundLocked(className, token, id, notification,
12971                    removeNotification);
12972        }
12973    }
12974
12975    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12976            boolean requireFull, String name, String callerPackage) {
12977        final int callingUserId = UserHandle.getUserId(callingUid);
12978        if (callingUserId != userId) {
12979            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12980                if ((requireFull || checkComponentPermission(
12981                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12982                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12983                        && checkComponentPermission(
12984                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12985                                callingPid, callingUid, -1, true)
12986                                != PackageManager.PERMISSION_GRANTED) {
12987                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12988                        // In this case, they would like to just execute as their
12989                        // owner user instead of failing.
12990                        userId = callingUserId;
12991                    } else {
12992                        StringBuilder builder = new StringBuilder(128);
12993                        builder.append("Permission Denial: ");
12994                        builder.append(name);
12995                        if (callerPackage != null) {
12996                            builder.append(" from ");
12997                            builder.append(callerPackage);
12998                        }
12999                        builder.append(" asks to run as user ");
13000                        builder.append(userId);
13001                        builder.append(" but is calling from user ");
13002                        builder.append(UserHandle.getUserId(callingUid));
13003                        builder.append("; this requires ");
13004                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13005                        if (!requireFull) {
13006                            builder.append(" or ");
13007                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13008                        }
13009                        String msg = builder.toString();
13010                        Slog.w(TAG, msg);
13011                        throw new SecurityException(msg);
13012                    }
13013                }
13014            }
13015            if (userId == UserHandle.USER_CURRENT
13016                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13017                // Note that we may be accessing this outside of a lock...
13018                // shouldn't be a big deal, if this is being called outside
13019                // of a locked context there is intrinsically a race with
13020                // the value the caller will receive and someone else changing it.
13021                userId = mCurrentUserId;
13022            }
13023            if (!allowAll && userId < 0) {
13024                throw new IllegalArgumentException(
13025                        "Call does not support special user #" + userId);
13026            }
13027        }
13028        return userId;
13029    }
13030
13031    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13032            String className, int flags) {
13033        boolean result = false;
13034        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13035            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13036                if (ActivityManager.checkUidPermission(
13037                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13038                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13039                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13040                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13041                            + " requests FLAG_SINGLE_USER, but app does not hold "
13042                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13043                    Slog.w(TAG, msg);
13044                    throw new SecurityException(msg);
13045                }
13046                result = true;
13047            }
13048        } else if (componentProcessName == aInfo.packageName) {
13049            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13050        } else if ("system".equals(componentProcessName)) {
13051            result = true;
13052        }
13053        if (DEBUG_MU) {
13054            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13055                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13056        }
13057        return result;
13058    }
13059
13060    public int bindService(IApplicationThread caller, IBinder token,
13061            Intent service, String resolvedType,
13062            IServiceConnection connection, int flags, int userId) {
13063        enforceNotIsolatedCaller("bindService");
13064        // Refuse possible leaked file descriptors
13065        if (service != null && service.hasFileDescriptors() == true) {
13066            throw new IllegalArgumentException("File descriptors passed in Intent");
13067        }
13068
13069        synchronized(this) {
13070            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13071                    connection, flags, userId);
13072        }
13073    }
13074
13075    public boolean unbindService(IServiceConnection connection) {
13076        synchronized (this) {
13077            return mServices.unbindServiceLocked(connection);
13078        }
13079    }
13080
13081    public void publishService(IBinder token, Intent intent, IBinder service) {
13082        // Refuse possible leaked file descriptors
13083        if (intent != null && intent.hasFileDescriptors() == true) {
13084            throw new IllegalArgumentException("File descriptors passed in Intent");
13085        }
13086
13087        synchronized(this) {
13088            if (!(token instanceof ServiceRecord)) {
13089                throw new IllegalArgumentException("Invalid service token");
13090            }
13091            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13092        }
13093    }
13094
13095    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13096        // Refuse possible leaked file descriptors
13097        if (intent != null && intent.hasFileDescriptors() == true) {
13098            throw new IllegalArgumentException("File descriptors passed in Intent");
13099        }
13100
13101        synchronized(this) {
13102            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13103        }
13104    }
13105
13106    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13107        synchronized(this) {
13108            if (!(token instanceof ServiceRecord)) {
13109                throw new IllegalArgumentException("Invalid service token");
13110            }
13111            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13112        }
13113    }
13114
13115    // =========================================================
13116    // BACKUP AND RESTORE
13117    // =========================================================
13118
13119    // Cause the target app to be launched if necessary and its backup agent
13120    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13121    // activity manager to announce its creation.
13122    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13123        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13124        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13125
13126        synchronized(this) {
13127            // !!! TODO: currently no check here that we're already bound
13128            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13129            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13130            synchronized (stats) {
13131                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13132            }
13133
13134            // Backup agent is now in use, its package can't be stopped.
13135            try {
13136                AppGlobals.getPackageManager().setPackageStoppedState(
13137                        app.packageName, false, UserHandle.getUserId(app.uid));
13138            } catch (RemoteException e) {
13139            } catch (IllegalArgumentException e) {
13140                Slog.w(TAG, "Failed trying to unstop package "
13141                        + app.packageName + ": " + e);
13142            }
13143
13144            BackupRecord r = new BackupRecord(ss, app, backupMode);
13145            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13146                    ? new ComponentName(app.packageName, app.backupAgentName)
13147                    : new ComponentName("android", "FullBackupAgent");
13148            // startProcessLocked() returns existing proc's record if it's already running
13149            ProcessRecord proc = startProcessLocked(app.processName, app,
13150                    false, 0, "backup", hostingName, false, false, false);
13151            if (proc == null) {
13152                Slog.e(TAG, "Unable to start backup agent process " + r);
13153                return false;
13154            }
13155
13156            r.app = proc;
13157            mBackupTarget = r;
13158            mBackupAppName = app.packageName;
13159
13160            // Try not to kill the process during backup
13161            updateOomAdjLocked(proc);
13162
13163            // If the process is already attached, schedule the creation of the backup agent now.
13164            // If it is not yet live, this will be done when it attaches to the framework.
13165            if (proc.thread != null) {
13166                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13167                try {
13168                    proc.thread.scheduleCreateBackupAgent(app,
13169                            compatibilityInfoForPackageLocked(app), backupMode);
13170                } catch (RemoteException e) {
13171                    // Will time out on the backup manager side
13172                }
13173            } else {
13174                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13175            }
13176            // Invariants: at this point, the target app process exists and the application
13177            // is either already running or in the process of coming up.  mBackupTarget and
13178            // mBackupAppName describe the app, so that when it binds back to the AM we
13179            // know that it's scheduled for a backup-agent operation.
13180        }
13181
13182        return true;
13183    }
13184
13185    @Override
13186    public void clearPendingBackup() {
13187        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13188        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13189
13190        synchronized (this) {
13191            mBackupTarget = null;
13192            mBackupAppName = null;
13193        }
13194    }
13195
13196    // A backup agent has just come up
13197    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13198        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13199                + " = " + agent);
13200
13201        synchronized(this) {
13202            if (!agentPackageName.equals(mBackupAppName)) {
13203                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13204                return;
13205            }
13206        }
13207
13208        long oldIdent = Binder.clearCallingIdentity();
13209        try {
13210            IBackupManager bm = IBackupManager.Stub.asInterface(
13211                    ServiceManager.getService(Context.BACKUP_SERVICE));
13212            bm.agentConnected(agentPackageName, agent);
13213        } catch (RemoteException e) {
13214            // can't happen; the backup manager service is local
13215        } catch (Exception e) {
13216            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13217            e.printStackTrace();
13218        } finally {
13219            Binder.restoreCallingIdentity(oldIdent);
13220        }
13221    }
13222
13223    // done with this agent
13224    public void unbindBackupAgent(ApplicationInfo appInfo) {
13225        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13226        if (appInfo == null) {
13227            Slog.w(TAG, "unbind backup agent for null app");
13228            return;
13229        }
13230
13231        synchronized(this) {
13232            try {
13233                if (mBackupAppName == null) {
13234                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13235                    return;
13236                }
13237
13238                if (!mBackupAppName.equals(appInfo.packageName)) {
13239                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13240                    return;
13241                }
13242
13243                // Not backing this app up any more; reset its OOM adjustment
13244                final ProcessRecord proc = mBackupTarget.app;
13245                updateOomAdjLocked(proc);
13246
13247                // If the app crashed during backup, 'thread' will be null here
13248                if (proc.thread != null) {
13249                    try {
13250                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13251                                compatibilityInfoForPackageLocked(appInfo));
13252                    } catch (Exception e) {
13253                        Slog.e(TAG, "Exception when unbinding backup agent:");
13254                        e.printStackTrace();
13255                    }
13256                }
13257            } finally {
13258                mBackupTarget = null;
13259                mBackupAppName = null;
13260            }
13261        }
13262    }
13263    // =========================================================
13264    // BROADCASTS
13265    // =========================================================
13266
13267    private final List getStickiesLocked(String action, IntentFilter filter,
13268            List cur, int userId) {
13269        final ContentResolver resolver = mContext.getContentResolver();
13270        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13271        if (stickies == null) {
13272            return cur;
13273        }
13274        final ArrayList<Intent> list = stickies.get(action);
13275        if (list == null) {
13276            return cur;
13277        }
13278        int N = list.size();
13279        for (int i=0; i<N; i++) {
13280            Intent intent = list.get(i);
13281            if (filter.match(resolver, intent, true, TAG) >= 0) {
13282                if (cur == null) {
13283                    cur = new ArrayList<Intent>();
13284                }
13285                cur.add(intent);
13286            }
13287        }
13288        return cur;
13289    }
13290
13291    boolean isPendingBroadcastProcessLocked(int pid) {
13292        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13293                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13294    }
13295
13296    void skipPendingBroadcastLocked(int pid) {
13297            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13298            for (BroadcastQueue queue : mBroadcastQueues) {
13299                queue.skipPendingBroadcastLocked(pid);
13300            }
13301    }
13302
13303    // The app just attached; send any pending broadcasts that it should receive
13304    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13305        boolean didSomething = false;
13306        for (BroadcastQueue queue : mBroadcastQueues) {
13307            didSomething |= queue.sendPendingBroadcastsLocked(app);
13308        }
13309        return didSomething;
13310    }
13311
13312    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13313            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13314        enforceNotIsolatedCaller("registerReceiver");
13315        int callingUid;
13316        int callingPid;
13317        synchronized(this) {
13318            ProcessRecord callerApp = null;
13319            if (caller != null) {
13320                callerApp = getRecordForAppLocked(caller);
13321                if (callerApp == null) {
13322                    throw new SecurityException(
13323                            "Unable to find app for caller " + caller
13324                            + " (pid=" + Binder.getCallingPid()
13325                            + ") when registering receiver " + receiver);
13326                }
13327                if (callerApp.info.uid != Process.SYSTEM_UID &&
13328                        !callerApp.pkgList.containsKey(callerPackage) &&
13329                        !"android".equals(callerPackage)) {
13330                    throw new SecurityException("Given caller package " + callerPackage
13331                            + " is not running in process " + callerApp);
13332                }
13333                callingUid = callerApp.info.uid;
13334                callingPid = callerApp.pid;
13335            } else {
13336                callerPackage = null;
13337                callingUid = Binder.getCallingUid();
13338                callingPid = Binder.getCallingPid();
13339            }
13340
13341            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13342                    true, true, "registerReceiver", callerPackage);
13343
13344            List allSticky = null;
13345
13346            // Look for any matching sticky broadcasts...
13347            Iterator actions = filter.actionsIterator();
13348            if (actions != null) {
13349                while (actions.hasNext()) {
13350                    String action = (String)actions.next();
13351                    allSticky = getStickiesLocked(action, filter, allSticky,
13352                            UserHandle.USER_ALL);
13353                    allSticky = getStickiesLocked(action, filter, allSticky,
13354                            UserHandle.getUserId(callingUid));
13355                }
13356            } else {
13357                allSticky = getStickiesLocked(null, filter, allSticky,
13358                        UserHandle.USER_ALL);
13359                allSticky = getStickiesLocked(null, filter, allSticky,
13360                        UserHandle.getUserId(callingUid));
13361            }
13362
13363            // The first sticky in the list is returned directly back to
13364            // the client.
13365            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13366
13367            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13368                    + ": " + sticky);
13369
13370            if (receiver == null) {
13371                return sticky;
13372            }
13373
13374            ReceiverList rl
13375                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13376            if (rl == null) {
13377                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13378                        userId, receiver);
13379                if (rl.app != null) {
13380                    rl.app.receivers.add(rl);
13381                } else {
13382                    try {
13383                        receiver.asBinder().linkToDeath(rl, 0);
13384                    } catch (RemoteException e) {
13385                        return sticky;
13386                    }
13387                    rl.linkedToDeath = true;
13388                }
13389                mRegisteredReceivers.put(receiver.asBinder(), rl);
13390            } else if (rl.uid != callingUid) {
13391                throw new IllegalArgumentException(
13392                        "Receiver requested to register for uid " + callingUid
13393                        + " was previously registered for uid " + rl.uid);
13394            } else if (rl.pid != callingPid) {
13395                throw new IllegalArgumentException(
13396                        "Receiver requested to register for pid " + callingPid
13397                        + " was previously registered for pid " + rl.pid);
13398            } else if (rl.userId != userId) {
13399                throw new IllegalArgumentException(
13400                        "Receiver requested to register for user " + userId
13401                        + " was previously registered for user " + rl.userId);
13402            }
13403            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13404                    permission, callingUid, userId);
13405            rl.add(bf);
13406            if (!bf.debugCheck()) {
13407                Slog.w(TAG, "==> For Dynamic broadast");
13408            }
13409            mReceiverResolver.addFilter(bf);
13410
13411            // Enqueue broadcasts for all existing stickies that match
13412            // this filter.
13413            if (allSticky != null) {
13414                ArrayList receivers = new ArrayList();
13415                receivers.add(bf);
13416
13417                int N = allSticky.size();
13418                for (int i=0; i<N; i++) {
13419                    Intent intent = (Intent)allSticky.get(i);
13420                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13421                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13422                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13423                            null, null, false, true, true, -1);
13424                    queue.enqueueParallelBroadcastLocked(r);
13425                    queue.scheduleBroadcastsLocked();
13426                }
13427            }
13428
13429            return sticky;
13430        }
13431    }
13432
13433    public void unregisterReceiver(IIntentReceiver receiver) {
13434        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13435
13436        final long origId = Binder.clearCallingIdentity();
13437        try {
13438            boolean doTrim = false;
13439
13440            synchronized(this) {
13441                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13442                if (rl != null) {
13443                    if (rl.curBroadcast != null) {
13444                        BroadcastRecord r = rl.curBroadcast;
13445                        final boolean doNext = finishReceiverLocked(
13446                                receiver.asBinder(), r.resultCode, r.resultData,
13447                                r.resultExtras, r.resultAbort);
13448                        if (doNext) {
13449                            doTrim = true;
13450                            r.queue.processNextBroadcast(false);
13451                        }
13452                    }
13453
13454                    if (rl.app != null) {
13455                        rl.app.receivers.remove(rl);
13456                    }
13457                    removeReceiverLocked(rl);
13458                    if (rl.linkedToDeath) {
13459                        rl.linkedToDeath = false;
13460                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13461                    }
13462                }
13463            }
13464
13465            // If we actually concluded any broadcasts, we might now be able
13466            // to trim the recipients' apps from our working set
13467            if (doTrim) {
13468                trimApplications();
13469                return;
13470            }
13471
13472        } finally {
13473            Binder.restoreCallingIdentity(origId);
13474        }
13475    }
13476
13477    void removeReceiverLocked(ReceiverList rl) {
13478        mRegisteredReceivers.remove(rl.receiver.asBinder());
13479        int N = rl.size();
13480        for (int i=0; i<N; i++) {
13481            mReceiverResolver.removeFilter(rl.get(i));
13482        }
13483    }
13484
13485    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13486        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13487            ProcessRecord r = mLruProcesses.get(i);
13488            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13489                try {
13490                    r.thread.dispatchPackageBroadcast(cmd, packages);
13491                } catch (RemoteException ex) {
13492                }
13493            }
13494        }
13495    }
13496
13497    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13498            int[] users) {
13499        List<ResolveInfo> receivers = null;
13500        try {
13501            HashSet<ComponentName> singleUserReceivers = null;
13502            boolean scannedFirstReceivers = false;
13503            for (int user : users) {
13504                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13505                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13506                if (user != 0 && newReceivers != null) {
13507                    // If this is not the primary user, we need to check for
13508                    // any receivers that should be filtered out.
13509                    for (int i=0; i<newReceivers.size(); i++) {
13510                        ResolveInfo ri = newReceivers.get(i);
13511                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13512                            newReceivers.remove(i);
13513                            i--;
13514                        }
13515                    }
13516                }
13517                if (newReceivers != null && newReceivers.size() == 0) {
13518                    newReceivers = null;
13519                }
13520                if (receivers == null) {
13521                    receivers = newReceivers;
13522                } else if (newReceivers != null) {
13523                    // We need to concatenate the additional receivers
13524                    // found with what we have do far.  This would be easy,
13525                    // but we also need to de-dup any receivers that are
13526                    // singleUser.
13527                    if (!scannedFirstReceivers) {
13528                        // Collect any single user receivers we had already retrieved.
13529                        scannedFirstReceivers = true;
13530                        for (int i=0; i<receivers.size(); i++) {
13531                            ResolveInfo ri = receivers.get(i);
13532                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13533                                ComponentName cn = new ComponentName(
13534                                        ri.activityInfo.packageName, ri.activityInfo.name);
13535                                if (singleUserReceivers == null) {
13536                                    singleUserReceivers = new HashSet<ComponentName>();
13537                                }
13538                                singleUserReceivers.add(cn);
13539                            }
13540                        }
13541                    }
13542                    // Add the new results to the existing results, tracking
13543                    // and de-dupping single user receivers.
13544                    for (int i=0; i<newReceivers.size(); i++) {
13545                        ResolveInfo ri = newReceivers.get(i);
13546                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13547                            ComponentName cn = new ComponentName(
13548                                    ri.activityInfo.packageName, ri.activityInfo.name);
13549                            if (singleUserReceivers == null) {
13550                                singleUserReceivers = new HashSet<ComponentName>();
13551                            }
13552                            if (!singleUserReceivers.contains(cn)) {
13553                                singleUserReceivers.add(cn);
13554                                receivers.add(ri);
13555                            }
13556                        } else {
13557                            receivers.add(ri);
13558                        }
13559                    }
13560                }
13561            }
13562        } catch (RemoteException ex) {
13563            // pm is in same process, this will never happen.
13564        }
13565        return receivers;
13566    }
13567
13568    private final int broadcastIntentLocked(ProcessRecord callerApp,
13569            String callerPackage, Intent intent, String resolvedType,
13570            IIntentReceiver resultTo, int resultCode, String resultData,
13571            Bundle map, String requiredPermission, int appOp,
13572            boolean ordered, boolean sticky, int callingPid, int callingUid,
13573            int userId) {
13574        intent = new Intent(intent);
13575
13576        // By default broadcasts do not go to stopped apps.
13577        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13578
13579        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13580            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13581            + " ordered=" + ordered + " userid=" + userId);
13582        if ((resultTo != null) && !ordered) {
13583            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13584        }
13585
13586        userId = handleIncomingUser(callingPid, callingUid, userId,
13587                true, false, "broadcast", callerPackage);
13588
13589        // Make sure that the user who is receiving this broadcast is started.
13590        // If not, we will just skip it.
13591        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13592            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13593                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13594                Slog.w(TAG, "Skipping broadcast of " + intent
13595                        + ": user " + userId + " is stopped");
13596                return ActivityManager.BROADCAST_SUCCESS;
13597            }
13598        }
13599
13600        /*
13601         * Prevent non-system code (defined here to be non-persistent
13602         * processes) from sending protected broadcasts.
13603         */
13604        int callingAppId = UserHandle.getAppId(callingUid);
13605        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13606            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13607            callingUid == 0) {
13608            // Always okay.
13609        } else if (callerApp == null || !callerApp.persistent) {
13610            try {
13611                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13612                        intent.getAction())) {
13613                    String msg = "Permission Denial: not allowed to send broadcast "
13614                            + intent.getAction() + " from pid="
13615                            + callingPid + ", uid=" + callingUid;
13616                    Slog.w(TAG, msg);
13617                    throw new SecurityException(msg);
13618                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13619                    // Special case for compatibility: we don't want apps to send this,
13620                    // but historically it has not been protected and apps may be using it
13621                    // to poke their own app widget.  So, instead of making it protected,
13622                    // just limit it to the caller.
13623                    if (callerApp == null) {
13624                        String msg = "Permission Denial: not allowed to send broadcast "
13625                                + intent.getAction() + " from unknown caller.";
13626                        Slog.w(TAG, msg);
13627                        throw new SecurityException(msg);
13628                    } else if (intent.getComponent() != null) {
13629                        // They are good enough to send to an explicit component...  verify
13630                        // it is being sent to the calling app.
13631                        if (!intent.getComponent().getPackageName().equals(
13632                                callerApp.info.packageName)) {
13633                            String msg = "Permission Denial: not allowed to send broadcast "
13634                                    + intent.getAction() + " to "
13635                                    + intent.getComponent().getPackageName() + " from "
13636                                    + callerApp.info.packageName;
13637                            Slog.w(TAG, msg);
13638                            throw new SecurityException(msg);
13639                        }
13640                    } else {
13641                        // Limit broadcast to their own package.
13642                        intent.setPackage(callerApp.info.packageName);
13643                    }
13644                }
13645            } catch (RemoteException e) {
13646                Slog.w(TAG, "Remote exception", e);
13647                return ActivityManager.BROADCAST_SUCCESS;
13648            }
13649        }
13650
13651        // Handle special intents: if this broadcast is from the package
13652        // manager about a package being removed, we need to remove all of
13653        // its activities from the history stack.
13654        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13655                intent.getAction());
13656        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13657                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13658                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13659                || uidRemoved) {
13660            if (checkComponentPermission(
13661                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13662                    callingPid, callingUid, -1, true)
13663                    == PackageManager.PERMISSION_GRANTED) {
13664                if (uidRemoved) {
13665                    final Bundle intentExtras = intent.getExtras();
13666                    final int uid = intentExtras != null
13667                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13668                    if (uid >= 0) {
13669                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13670                        synchronized (bs) {
13671                            bs.removeUidStatsLocked(uid);
13672                        }
13673                        mAppOpsService.uidRemoved(uid);
13674                    }
13675                } else {
13676                    // If resources are unavailable just force stop all
13677                    // those packages and flush the attribute cache as well.
13678                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13679                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13680                        if (list != null && (list.length > 0)) {
13681                            for (String pkg : list) {
13682                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13683                                        "storage unmount");
13684                            }
13685                            sendPackageBroadcastLocked(
13686                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13687                        }
13688                    } else {
13689                        Uri data = intent.getData();
13690                        String ssp;
13691                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13692                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13693                                    intent.getAction());
13694                            boolean fullUninstall = removed &&
13695                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13696                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13697                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13698                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13699                                        false, fullUninstall, userId,
13700                                        removed ? "pkg removed" : "pkg changed");
13701                            }
13702                            if (removed) {
13703                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13704                                        new String[] {ssp}, userId);
13705                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13706                                    mAppOpsService.packageRemoved(
13707                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13708
13709                                    // Remove all permissions granted from/to this package
13710                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13711                                }
13712                            }
13713                        }
13714                    }
13715                }
13716            } else {
13717                String msg = "Permission Denial: " + intent.getAction()
13718                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13719                        + ", uid=" + callingUid + ")"
13720                        + " requires "
13721                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13722                Slog.w(TAG, msg);
13723                throw new SecurityException(msg);
13724            }
13725
13726        // Special case for adding a package: by default turn on compatibility
13727        // mode.
13728        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13729            Uri data = intent.getData();
13730            String ssp;
13731            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13732                mCompatModePackages.handlePackageAddedLocked(ssp,
13733                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13734            }
13735        }
13736
13737        /*
13738         * If this is the time zone changed action, queue up a message that will reset the timezone
13739         * of all currently running processes. This message will get queued up before the broadcast
13740         * happens.
13741         */
13742        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13743            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13744        }
13745
13746        /*
13747         * If the user set the time, let all running processes know.
13748         */
13749        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13750            final int is24Hour = intent.getBooleanExtra(
13751                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13752            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13753        }
13754
13755        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13756            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13757        }
13758
13759        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13760            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13761            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13762        }
13763
13764        // Add to the sticky list if requested.
13765        if (sticky) {
13766            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13767                    callingPid, callingUid)
13768                    != PackageManager.PERMISSION_GRANTED) {
13769                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13770                        + callingPid + ", uid=" + callingUid
13771                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13772                Slog.w(TAG, msg);
13773                throw new SecurityException(msg);
13774            }
13775            if (requiredPermission != null) {
13776                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13777                        + " and enforce permission " + requiredPermission);
13778                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13779            }
13780            if (intent.getComponent() != null) {
13781                throw new SecurityException(
13782                        "Sticky broadcasts can't target a specific component");
13783            }
13784            // We use userId directly here, since the "all" target is maintained
13785            // as a separate set of sticky broadcasts.
13786            if (userId != UserHandle.USER_ALL) {
13787                // But first, if this is not a broadcast to all users, then
13788                // make sure it doesn't conflict with an existing broadcast to
13789                // all users.
13790                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13791                        UserHandle.USER_ALL);
13792                if (stickies != null) {
13793                    ArrayList<Intent> list = stickies.get(intent.getAction());
13794                    if (list != null) {
13795                        int N = list.size();
13796                        int i;
13797                        for (i=0; i<N; i++) {
13798                            if (intent.filterEquals(list.get(i))) {
13799                                throw new IllegalArgumentException(
13800                                        "Sticky broadcast " + intent + " for user "
13801                                        + userId + " conflicts with existing global broadcast");
13802                            }
13803                        }
13804                    }
13805                }
13806            }
13807            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13808            if (stickies == null) {
13809                stickies = new ArrayMap<String, ArrayList<Intent>>();
13810                mStickyBroadcasts.put(userId, stickies);
13811            }
13812            ArrayList<Intent> list = stickies.get(intent.getAction());
13813            if (list == null) {
13814                list = new ArrayList<Intent>();
13815                stickies.put(intent.getAction(), list);
13816            }
13817            int N = list.size();
13818            int i;
13819            for (i=0; i<N; i++) {
13820                if (intent.filterEquals(list.get(i))) {
13821                    // This sticky already exists, replace it.
13822                    list.set(i, new Intent(intent));
13823                    break;
13824                }
13825            }
13826            if (i >= N) {
13827                list.add(new Intent(intent));
13828            }
13829        }
13830
13831        int[] users;
13832        if (userId == UserHandle.USER_ALL) {
13833            // Caller wants broadcast to go to all started users.
13834            users = mStartedUserArray;
13835        } else {
13836            // Caller wants broadcast to go to one specific user.
13837            users = new int[] {userId};
13838        }
13839
13840        // Figure out who all will receive this broadcast.
13841        List receivers = null;
13842        List<BroadcastFilter> registeredReceivers = null;
13843        // Need to resolve the intent to interested receivers...
13844        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13845                 == 0) {
13846            receivers = collectReceiverComponents(intent, resolvedType, users);
13847        }
13848        if (intent.getComponent() == null) {
13849            registeredReceivers = mReceiverResolver.queryIntent(intent,
13850                    resolvedType, false, userId);
13851        }
13852
13853        final boolean replacePending =
13854                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13855
13856        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13857                + " replacePending=" + replacePending);
13858
13859        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13860        if (!ordered && NR > 0) {
13861            // If we are not serializing this broadcast, then send the
13862            // registered receivers separately so they don't wait for the
13863            // components to be launched.
13864            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13865            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13866                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13867                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13868                    ordered, sticky, false, userId);
13869            if (DEBUG_BROADCAST) Slog.v(
13870                    TAG, "Enqueueing parallel broadcast " + r);
13871            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13872            if (!replaced) {
13873                queue.enqueueParallelBroadcastLocked(r);
13874                queue.scheduleBroadcastsLocked();
13875            }
13876            registeredReceivers = null;
13877            NR = 0;
13878        }
13879
13880        // Merge into one list.
13881        int ir = 0;
13882        if (receivers != null) {
13883            // A special case for PACKAGE_ADDED: do not allow the package
13884            // being added to see this broadcast.  This prevents them from
13885            // using this as a back door to get run as soon as they are
13886            // installed.  Maybe in the future we want to have a special install
13887            // broadcast or such for apps, but we'd like to deliberately make
13888            // this decision.
13889            String skipPackages[] = null;
13890            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13891                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13892                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13893                Uri data = intent.getData();
13894                if (data != null) {
13895                    String pkgName = data.getSchemeSpecificPart();
13896                    if (pkgName != null) {
13897                        skipPackages = new String[] { pkgName };
13898                    }
13899                }
13900            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13901                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13902            }
13903            if (skipPackages != null && (skipPackages.length > 0)) {
13904                for (String skipPackage : skipPackages) {
13905                    if (skipPackage != null) {
13906                        int NT = receivers.size();
13907                        for (int it=0; it<NT; it++) {
13908                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13909                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13910                                receivers.remove(it);
13911                                it--;
13912                                NT--;
13913                            }
13914                        }
13915                    }
13916                }
13917            }
13918
13919            int NT = receivers != null ? receivers.size() : 0;
13920            int it = 0;
13921            ResolveInfo curt = null;
13922            BroadcastFilter curr = null;
13923            while (it < NT && ir < NR) {
13924                if (curt == null) {
13925                    curt = (ResolveInfo)receivers.get(it);
13926                }
13927                if (curr == null) {
13928                    curr = registeredReceivers.get(ir);
13929                }
13930                if (curr.getPriority() >= curt.priority) {
13931                    // Insert this broadcast record into the final list.
13932                    receivers.add(it, curr);
13933                    ir++;
13934                    curr = null;
13935                    it++;
13936                    NT++;
13937                } else {
13938                    // Skip to the next ResolveInfo in the final list.
13939                    it++;
13940                    curt = null;
13941                }
13942            }
13943        }
13944        while (ir < NR) {
13945            if (receivers == null) {
13946                receivers = new ArrayList();
13947            }
13948            receivers.add(registeredReceivers.get(ir));
13949            ir++;
13950        }
13951
13952        if ((receivers != null && receivers.size() > 0)
13953                || resultTo != null) {
13954            BroadcastQueue queue = broadcastQueueForIntent(intent);
13955            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13956                    callerPackage, callingPid, callingUid, resolvedType,
13957                    requiredPermission, appOp, receivers, resultTo, resultCode,
13958                    resultData, map, ordered, sticky, false, userId);
13959            if (DEBUG_BROADCAST) Slog.v(
13960                    TAG, "Enqueueing ordered broadcast " + r
13961                    + ": prev had " + queue.mOrderedBroadcasts.size());
13962            if (DEBUG_BROADCAST) {
13963                int seq = r.intent.getIntExtra("seq", -1);
13964                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13965            }
13966            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13967            if (!replaced) {
13968                queue.enqueueOrderedBroadcastLocked(r);
13969                queue.scheduleBroadcastsLocked();
13970            }
13971        }
13972
13973        return ActivityManager.BROADCAST_SUCCESS;
13974    }
13975
13976    final Intent verifyBroadcastLocked(Intent intent) {
13977        // Refuse possible leaked file descriptors
13978        if (intent != null && intent.hasFileDescriptors() == true) {
13979            throw new IllegalArgumentException("File descriptors passed in Intent");
13980        }
13981
13982        int flags = intent.getFlags();
13983
13984        if (!mProcessesReady) {
13985            // if the caller really truly claims to know what they're doing, go
13986            // ahead and allow the broadcast without launching any receivers
13987            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13988                intent = new Intent(intent);
13989                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13990            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13991                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13992                        + " before boot completion");
13993                throw new IllegalStateException("Cannot broadcast before boot completed");
13994            }
13995        }
13996
13997        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13998            throw new IllegalArgumentException(
13999                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14000        }
14001
14002        return intent;
14003    }
14004
14005    public final int broadcastIntent(IApplicationThread caller,
14006            Intent intent, String resolvedType, IIntentReceiver resultTo,
14007            int resultCode, String resultData, Bundle map,
14008            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14009        enforceNotIsolatedCaller("broadcastIntent");
14010        synchronized(this) {
14011            intent = verifyBroadcastLocked(intent);
14012
14013            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14014            final int callingPid = Binder.getCallingPid();
14015            final int callingUid = Binder.getCallingUid();
14016            final long origId = Binder.clearCallingIdentity();
14017            int res = broadcastIntentLocked(callerApp,
14018                    callerApp != null ? callerApp.info.packageName : null,
14019                    intent, resolvedType, resultTo,
14020                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14021                    callingPid, callingUid, userId);
14022            Binder.restoreCallingIdentity(origId);
14023            return res;
14024        }
14025    }
14026
14027    int broadcastIntentInPackage(String packageName, int uid,
14028            Intent intent, String resolvedType, IIntentReceiver resultTo,
14029            int resultCode, String resultData, Bundle map,
14030            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14031        synchronized(this) {
14032            intent = verifyBroadcastLocked(intent);
14033
14034            final long origId = Binder.clearCallingIdentity();
14035            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14036                    resultTo, resultCode, resultData, map, requiredPermission,
14037                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14038            Binder.restoreCallingIdentity(origId);
14039            return res;
14040        }
14041    }
14042
14043    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14044        // Refuse possible leaked file descriptors
14045        if (intent != null && intent.hasFileDescriptors() == true) {
14046            throw new IllegalArgumentException("File descriptors passed in Intent");
14047        }
14048
14049        userId = handleIncomingUser(Binder.getCallingPid(),
14050                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14051
14052        synchronized(this) {
14053            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14054                    != PackageManager.PERMISSION_GRANTED) {
14055                String msg = "Permission Denial: unbroadcastIntent() from pid="
14056                        + Binder.getCallingPid()
14057                        + ", uid=" + Binder.getCallingUid()
14058                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14059                Slog.w(TAG, msg);
14060                throw new SecurityException(msg);
14061            }
14062            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14063            if (stickies != null) {
14064                ArrayList<Intent> list = stickies.get(intent.getAction());
14065                if (list != null) {
14066                    int N = list.size();
14067                    int i;
14068                    for (i=0; i<N; i++) {
14069                        if (intent.filterEquals(list.get(i))) {
14070                            list.remove(i);
14071                            break;
14072                        }
14073                    }
14074                    if (list.size() <= 0) {
14075                        stickies.remove(intent.getAction());
14076                    }
14077                }
14078                if (stickies.size() <= 0) {
14079                    mStickyBroadcasts.remove(userId);
14080                }
14081            }
14082        }
14083    }
14084
14085    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14086            String resultData, Bundle resultExtras, boolean resultAbort) {
14087        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14088        if (r == null) {
14089            Slog.w(TAG, "finishReceiver called but not found on queue");
14090            return false;
14091        }
14092
14093        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14094    }
14095
14096    void backgroundServicesFinishedLocked(int userId) {
14097        for (BroadcastQueue queue : mBroadcastQueues) {
14098            queue.backgroundServicesFinishedLocked(userId);
14099        }
14100    }
14101
14102    public void finishReceiver(IBinder who, int resultCode, String resultData,
14103            Bundle resultExtras, boolean resultAbort) {
14104        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14105
14106        // Refuse possible leaked file descriptors
14107        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14108            throw new IllegalArgumentException("File descriptors passed in Bundle");
14109        }
14110
14111        final long origId = Binder.clearCallingIdentity();
14112        try {
14113            boolean doNext = false;
14114            BroadcastRecord r;
14115
14116            synchronized(this) {
14117                r = broadcastRecordForReceiverLocked(who);
14118                if (r != null) {
14119                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14120                        resultData, resultExtras, resultAbort, true);
14121                }
14122            }
14123
14124            if (doNext) {
14125                r.queue.processNextBroadcast(false);
14126            }
14127            trimApplications();
14128        } finally {
14129            Binder.restoreCallingIdentity(origId);
14130        }
14131    }
14132
14133    // =========================================================
14134    // INSTRUMENTATION
14135    // =========================================================
14136
14137    public boolean startInstrumentation(ComponentName className,
14138            String profileFile, int flags, Bundle arguments,
14139            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14140            int userId) {
14141        enforceNotIsolatedCaller("startInstrumentation");
14142        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14143                userId, false, true, "startInstrumentation", null);
14144        // Refuse possible leaked file descriptors
14145        if (arguments != null && arguments.hasFileDescriptors()) {
14146            throw new IllegalArgumentException("File descriptors passed in Bundle");
14147        }
14148
14149        synchronized(this) {
14150            InstrumentationInfo ii = null;
14151            ApplicationInfo ai = null;
14152            try {
14153                ii = mContext.getPackageManager().getInstrumentationInfo(
14154                    className, STOCK_PM_FLAGS);
14155                ai = AppGlobals.getPackageManager().getApplicationInfo(
14156                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14157            } catch (PackageManager.NameNotFoundException e) {
14158            } catch (RemoteException e) {
14159            }
14160            if (ii == null) {
14161                reportStartInstrumentationFailure(watcher, className,
14162                        "Unable to find instrumentation info for: " + className);
14163                return false;
14164            }
14165            if (ai == null) {
14166                reportStartInstrumentationFailure(watcher, className,
14167                        "Unable to find instrumentation target package: " + ii.targetPackage);
14168                return false;
14169            }
14170
14171            int match = mContext.getPackageManager().checkSignatures(
14172                    ii.targetPackage, ii.packageName);
14173            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14174                String msg = "Permission Denial: starting instrumentation "
14175                        + className + " from pid="
14176                        + Binder.getCallingPid()
14177                        + ", uid=" + Binder.getCallingPid()
14178                        + " not allowed because package " + ii.packageName
14179                        + " does not have a signature matching the target "
14180                        + ii.targetPackage;
14181                reportStartInstrumentationFailure(watcher, className, msg);
14182                throw new SecurityException(msg);
14183            }
14184
14185            final long origId = Binder.clearCallingIdentity();
14186            // Instrumentation can kill and relaunch even persistent processes
14187            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14188                    "start instr");
14189            ProcessRecord app = addAppLocked(ai, false);
14190            app.instrumentationClass = className;
14191            app.instrumentationInfo = ai;
14192            app.instrumentationProfileFile = profileFile;
14193            app.instrumentationArguments = arguments;
14194            app.instrumentationWatcher = watcher;
14195            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14196            app.instrumentationResultClass = className;
14197            Binder.restoreCallingIdentity(origId);
14198        }
14199
14200        return true;
14201    }
14202
14203    /**
14204     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14205     * error to the logs, but if somebody is watching, send the report there too.  This enables
14206     * the "am" command to report errors with more information.
14207     *
14208     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14209     * @param cn The component name of the instrumentation.
14210     * @param report The error report.
14211     */
14212    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14213            ComponentName cn, String report) {
14214        Slog.w(TAG, report);
14215        try {
14216            if (watcher != null) {
14217                Bundle results = new Bundle();
14218                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14219                results.putString("Error", report);
14220                watcher.instrumentationStatus(cn, -1, results);
14221            }
14222        } catch (RemoteException e) {
14223            Slog.w(TAG, e);
14224        }
14225    }
14226
14227    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14228        if (app.instrumentationWatcher != null) {
14229            try {
14230                // NOTE:  IInstrumentationWatcher *must* be oneway here
14231                app.instrumentationWatcher.instrumentationFinished(
14232                    app.instrumentationClass,
14233                    resultCode,
14234                    results);
14235            } catch (RemoteException e) {
14236            }
14237        }
14238        if (app.instrumentationUiAutomationConnection != null) {
14239            try {
14240                app.instrumentationUiAutomationConnection.shutdown();
14241            } catch (RemoteException re) {
14242                /* ignore */
14243            }
14244            // Only a UiAutomation can set this flag and now that
14245            // it is finished we make sure it is reset to its default.
14246            mUserIsMonkey = false;
14247        }
14248        app.instrumentationWatcher = null;
14249        app.instrumentationUiAutomationConnection = null;
14250        app.instrumentationClass = null;
14251        app.instrumentationInfo = null;
14252        app.instrumentationProfileFile = null;
14253        app.instrumentationArguments = null;
14254
14255        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14256                "finished inst");
14257    }
14258
14259    public void finishInstrumentation(IApplicationThread target,
14260            int resultCode, Bundle results) {
14261        int userId = UserHandle.getCallingUserId();
14262        // Refuse possible leaked file descriptors
14263        if (results != null && results.hasFileDescriptors()) {
14264            throw new IllegalArgumentException("File descriptors passed in Intent");
14265        }
14266
14267        synchronized(this) {
14268            ProcessRecord app = getRecordForAppLocked(target);
14269            if (app == null) {
14270                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14271                return;
14272            }
14273            final long origId = Binder.clearCallingIdentity();
14274            finishInstrumentationLocked(app, resultCode, results);
14275            Binder.restoreCallingIdentity(origId);
14276        }
14277    }
14278
14279    // =========================================================
14280    // CONFIGURATION
14281    // =========================================================
14282
14283    public ConfigurationInfo getDeviceConfigurationInfo() {
14284        ConfigurationInfo config = new ConfigurationInfo();
14285        synchronized (this) {
14286            config.reqTouchScreen = mConfiguration.touchscreen;
14287            config.reqKeyboardType = mConfiguration.keyboard;
14288            config.reqNavigation = mConfiguration.navigation;
14289            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14290                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14291                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14292            }
14293            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14294                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14295                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14296            }
14297            config.reqGlEsVersion = GL_ES_VERSION;
14298        }
14299        return config;
14300    }
14301
14302    ActivityStack getFocusedStack() {
14303        return mStackSupervisor.getFocusedStack();
14304    }
14305
14306    public Configuration getConfiguration() {
14307        Configuration ci;
14308        synchronized(this) {
14309            ci = new Configuration(mConfiguration);
14310        }
14311        return ci;
14312    }
14313
14314    public void updatePersistentConfiguration(Configuration values) {
14315        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14316                "updateConfiguration()");
14317        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14318                "updateConfiguration()");
14319        if (values == null) {
14320            throw new NullPointerException("Configuration must not be null");
14321        }
14322
14323        synchronized(this) {
14324            final long origId = Binder.clearCallingIdentity();
14325            updateConfigurationLocked(values, null, true, false);
14326            Binder.restoreCallingIdentity(origId);
14327        }
14328    }
14329
14330    public void updateConfiguration(Configuration values) {
14331        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14332                "updateConfiguration()");
14333
14334        synchronized(this) {
14335            if (values == null && mWindowManager != null) {
14336                // sentinel: fetch the current configuration from the window manager
14337                values = mWindowManager.computeNewConfiguration();
14338            }
14339
14340            if (mWindowManager != null) {
14341                mProcessList.applyDisplaySize(mWindowManager);
14342            }
14343
14344            final long origId = Binder.clearCallingIdentity();
14345            if (values != null) {
14346                Settings.System.clearConfiguration(values);
14347            }
14348            updateConfigurationLocked(values, null, false, false);
14349            Binder.restoreCallingIdentity(origId);
14350        }
14351    }
14352
14353    /**
14354     * Do either or both things: (1) change the current configuration, and (2)
14355     * make sure the given activity is running with the (now) current
14356     * configuration.  Returns true if the activity has been left running, or
14357     * false if <var>starting</var> is being destroyed to match the new
14358     * configuration.
14359     * @param persistent TODO
14360     */
14361    boolean updateConfigurationLocked(Configuration values,
14362            ActivityRecord starting, boolean persistent, boolean initLocale) {
14363        int changes = 0;
14364
14365        if (values != null) {
14366            Configuration newConfig = new Configuration(mConfiguration);
14367            changes = newConfig.updateFrom(values);
14368            if (changes != 0) {
14369                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14370                    Slog.i(TAG, "Updating configuration to: " + values);
14371                }
14372
14373                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14374
14375                if (values.locale != null && !initLocale) {
14376                    saveLocaleLocked(values.locale,
14377                                     !values.locale.equals(mConfiguration.locale),
14378                                     values.userSetLocale);
14379                }
14380
14381                mConfigurationSeq++;
14382                if (mConfigurationSeq <= 0) {
14383                    mConfigurationSeq = 1;
14384                }
14385                newConfig.seq = mConfigurationSeq;
14386                mConfiguration = newConfig;
14387                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14388
14389                final Configuration configCopy = new Configuration(mConfiguration);
14390
14391                // TODO: If our config changes, should we auto dismiss any currently
14392                // showing dialogs?
14393                mShowDialogs = shouldShowDialogs(newConfig);
14394
14395                AttributeCache ac = AttributeCache.instance();
14396                if (ac != null) {
14397                    ac.updateConfiguration(configCopy);
14398                }
14399
14400                // Make sure all resources in our process are updated
14401                // right now, so that anyone who is going to retrieve
14402                // resource values after we return will be sure to get
14403                // the new ones.  This is especially important during
14404                // boot, where the first config change needs to guarantee
14405                // all resources have that config before following boot
14406                // code is executed.
14407                mSystemThread.applyConfigurationToResources(configCopy);
14408
14409                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14410                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14411                    msg.obj = new Configuration(configCopy);
14412                    mHandler.sendMessage(msg);
14413                }
14414
14415                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14416                    ProcessRecord app = mLruProcesses.get(i);
14417                    try {
14418                        if (app.thread != null) {
14419                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14420                                    + app.processName + " new config " + mConfiguration);
14421                            app.thread.scheduleConfigurationChanged(configCopy);
14422                        }
14423                    } catch (Exception e) {
14424                    }
14425                }
14426                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14427                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14428                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14429                        | Intent.FLAG_RECEIVER_FOREGROUND);
14430                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14431                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14432                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14433                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14434                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14435                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14436                    broadcastIntentLocked(null, null, intent,
14437                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14438                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14439                }
14440            }
14441        }
14442
14443        boolean kept = true;
14444        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14445        // mainStack is null during startup.
14446        if (mainStack != null) {
14447            if (changes != 0 && starting == null) {
14448                // If the configuration changed, and the caller is not already
14449                // in the process of starting an activity, then find the top
14450                // activity to check if its configuration needs to change.
14451                starting = mainStack.topRunningActivityLocked(null);
14452            }
14453
14454            if (starting != null) {
14455                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14456                // And we need to make sure at this point that all other activities
14457                // are made visible with the correct configuration.
14458                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14459            }
14460        }
14461
14462        if (values != null && mWindowManager != null) {
14463            mWindowManager.setNewConfiguration(mConfiguration);
14464        }
14465
14466        return kept;
14467    }
14468
14469    /**
14470     * Decide based on the configuration whether we should shouw the ANR,
14471     * crash, etc dialogs.  The idea is that if there is no affordnace to
14472     * press the on-screen buttons, we shouldn't show the dialog.
14473     *
14474     * A thought: SystemUI might also want to get told about this, the Power
14475     * dialog / global actions also might want different behaviors.
14476     */
14477    private static final boolean shouldShowDialogs(Configuration config) {
14478        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14479                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14480    }
14481
14482    /**
14483     * Save the locale.  You must be inside a synchronized (this) block.
14484     */
14485    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14486        if(isDiff) {
14487            SystemProperties.set("user.language", l.getLanguage());
14488            SystemProperties.set("user.region", l.getCountry());
14489        }
14490
14491        if(isPersist) {
14492            SystemProperties.set("persist.sys.language", l.getLanguage());
14493            SystemProperties.set("persist.sys.country", l.getCountry());
14494            SystemProperties.set("persist.sys.localevar", l.getVariant());
14495        }
14496    }
14497
14498    @Override
14499    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14500        ActivityRecord srec = ActivityRecord.forToken(token);
14501        return srec != null && srec.task.affinity != null &&
14502                srec.task.affinity.equals(destAffinity);
14503    }
14504
14505    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14506            Intent resultData) {
14507
14508        synchronized (this) {
14509            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14510            if (stack != null) {
14511                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14512            }
14513            return false;
14514        }
14515    }
14516
14517    public int getLaunchedFromUid(IBinder activityToken) {
14518        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14519        if (srec == null) {
14520            return -1;
14521        }
14522        return srec.launchedFromUid;
14523    }
14524
14525    public String getLaunchedFromPackage(IBinder activityToken) {
14526        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14527        if (srec == null) {
14528            return null;
14529        }
14530        return srec.launchedFromPackage;
14531    }
14532
14533    // =========================================================
14534    // LIFETIME MANAGEMENT
14535    // =========================================================
14536
14537    // Returns which broadcast queue the app is the current [or imminent] receiver
14538    // on, or 'null' if the app is not an active broadcast recipient.
14539    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14540        BroadcastRecord r = app.curReceiver;
14541        if (r != null) {
14542            return r.queue;
14543        }
14544
14545        // It's not the current receiver, but it might be starting up to become one
14546        synchronized (this) {
14547            for (BroadcastQueue queue : mBroadcastQueues) {
14548                r = queue.mPendingBroadcast;
14549                if (r != null && r.curApp == app) {
14550                    // found it; report which queue it's in
14551                    return queue;
14552                }
14553            }
14554        }
14555
14556        return null;
14557    }
14558
14559    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14560            boolean doingAll, long now) {
14561        if (mAdjSeq == app.adjSeq) {
14562            // This adjustment has already been computed.
14563            return app.curRawAdj;
14564        }
14565
14566        if (app.thread == null) {
14567            app.adjSeq = mAdjSeq;
14568            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14569            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14570            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14571        }
14572
14573        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14574        app.adjSource = null;
14575        app.adjTarget = null;
14576        app.empty = false;
14577        app.cached = false;
14578
14579        final int activitiesSize = app.activities.size();
14580
14581        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14582            // The max adjustment doesn't allow this app to be anything
14583            // below foreground, so it is not worth doing work for it.
14584            app.adjType = "fixed";
14585            app.adjSeq = mAdjSeq;
14586            app.curRawAdj = app.maxAdj;
14587            app.foregroundActivities = false;
14588            app.keeping = true;
14589            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14590            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14591            // System processes can do UI, and when they do we want to have
14592            // them trim their memory after the user leaves the UI.  To
14593            // facilitate this, here we need to determine whether or not it
14594            // is currently showing UI.
14595            app.systemNoUi = true;
14596            if (app == TOP_APP) {
14597                app.systemNoUi = false;
14598            } else if (activitiesSize > 0) {
14599                for (int j = 0; j < activitiesSize; j++) {
14600                    final ActivityRecord r = app.activities.get(j);
14601                    if (r.visible) {
14602                        app.systemNoUi = false;
14603                    }
14604                }
14605            }
14606            if (!app.systemNoUi) {
14607                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14608            }
14609            return (app.curAdj=app.maxAdj);
14610        }
14611
14612        app.keeping = false;
14613        app.systemNoUi = false;
14614
14615        // Determine the importance of the process, starting with most
14616        // important to least, and assign an appropriate OOM adjustment.
14617        int adj;
14618        int schedGroup;
14619        int procState;
14620        boolean foregroundActivities = false;
14621        boolean interesting = false;
14622        BroadcastQueue queue;
14623        if (app == TOP_APP) {
14624            // The last app on the list is the foreground app.
14625            adj = ProcessList.FOREGROUND_APP_ADJ;
14626            schedGroup = Process.THREAD_GROUP_DEFAULT;
14627            app.adjType = "top-activity";
14628            foregroundActivities = true;
14629            interesting = true;
14630            procState = ActivityManager.PROCESS_STATE_TOP;
14631        } else if (app.instrumentationClass != null) {
14632            // Don't want to kill running instrumentation.
14633            adj = ProcessList.FOREGROUND_APP_ADJ;
14634            schedGroup = Process.THREAD_GROUP_DEFAULT;
14635            app.adjType = "instrumentation";
14636            interesting = true;
14637            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14638        } else if ((queue = isReceivingBroadcast(app)) != null) {
14639            // An app that is currently receiving a broadcast also
14640            // counts as being in the foreground for OOM killer purposes.
14641            // It's placed in a sched group based on the nature of the
14642            // broadcast as reflected by which queue it's active in.
14643            adj = ProcessList.FOREGROUND_APP_ADJ;
14644            schedGroup = (queue == mFgBroadcastQueue)
14645                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14646            app.adjType = "broadcast";
14647            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14648        } else if (app.executingServices.size() > 0) {
14649            // An app that is currently executing a service callback also
14650            // counts as being in the foreground.
14651            adj = ProcessList.FOREGROUND_APP_ADJ;
14652            schedGroup = app.execServicesFg ?
14653                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14654            app.adjType = "exec-service";
14655            procState = ActivityManager.PROCESS_STATE_SERVICE;
14656            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14657        } else {
14658            // As far as we know the process is empty.  We may change our mind later.
14659            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14660            // At this point we don't actually know the adjustment.  Use the cached adj
14661            // value that the caller wants us to.
14662            adj = cachedAdj;
14663            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14664            app.cached = true;
14665            app.empty = true;
14666            app.adjType = "cch-empty";
14667        }
14668
14669        // Examine all activities if not already foreground.
14670        if (!foregroundActivities && activitiesSize > 0) {
14671            for (int j = 0; j < activitiesSize; j++) {
14672                final ActivityRecord r = app.activities.get(j);
14673                if (r.app != app) {
14674                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14675                            + app + "?!?");
14676                    continue;
14677                }
14678                if (r.visible) {
14679                    // App has a visible activity; only upgrade adjustment.
14680                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14681                        adj = ProcessList.VISIBLE_APP_ADJ;
14682                        app.adjType = "visible";
14683                    }
14684                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14685                        procState = ActivityManager.PROCESS_STATE_TOP;
14686                    }
14687                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14688                    app.cached = false;
14689                    app.empty = false;
14690                    foregroundActivities = true;
14691                    break;
14692                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14693                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14694                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14695                        app.adjType = "pausing";
14696                    }
14697                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14698                        procState = ActivityManager.PROCESS_STATE_TOP;
14699                    }
14700                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14701                    app.cached = false;
14702                    app.empty = false;
14703                    foregroundActivities = true;
14704                } else if (r.state == ActivityState.STOPPING) {
14705                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14706                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14707                        app.adjType = "stopping";
14708                    }
14709                    // For the process state, we will at this point consider the
14710                    // process to be cached.  It will be cached either as an activity
14711                    // or empty depending on whether the activity is finishing.  We do
14712                    // this so that we can treat the process as cached for purposes of
14713                    // memory trimming (determing current memory level, trim command to
14714                    // send to process) since there can be an arbitrary number of stopping
14715                    // processes and they should soon all go into the cached state.
14716                    if (!r.finishing) {
14717                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14718                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14719                        }
14720                    }
14721                    app.cached = false;
14722                    app.empty = false;
14723                    foregroundActivities = true;
14724                } else {
14725                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14726                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14727                        app.adjType = "cch-act";
14728                    }
14729                }
14730            }
14731        }
14732
14733        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14734            if (app.foregroundServices) {
14735                // The user is aware of this app, so make it visible.
14736                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14737                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14738                app.cached = false;
14739                app.adjType = "fg-service";
14740                schedGroup = Process.THREAD_GROUP_DEFAULT;
14741            } else if (app.forcingToForeground != null) {
14742                // The user is aware of this app, so make it visible.
14743                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14744                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14745                app.cached = false;
14746                app.adjType = "force-fg";
14747                app.adjSource = app.forcingToForeground;
14748                schedGroup = Process.THREAD_GROUP_DEFAULT;
14749            }
14750        }
14751
14752        if (app.foregroundServices) {
14753            interesting = true;
14754        }
14755
14756        if (app == mHeavyWeightProcess) {
14757            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14758                // We don't want to kill the current heavy-weight process.
14759                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14760                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14761                app.cached = false;
14762                app.adjType = "heavy";
14763            }
14764            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14765                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14766            }
14767        }
14768
14769        if (app == mHomeProcess) {
14770            if (adj > ProcessList.HOME_APP_ADJ) {
14771                // This process is hosting what we currently consider to be the
14772                // home app, so we don't want to let it go into the background.
14773                adj = ProcessList.HOME_APP_ADJ;
14774                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14775                app.cached = false;
14776                app.adjType = "home";
14777            }
14778            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14779                procState = ActivityManager.PROCESS_STATE_HOME;
14780            }
14781        }
14782
14783        if (app == mPreviousProcess && app.activities.size() > 0) {
14784            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14785                // This was the previous process that showed UI to the user.
14786                // We want to try to keep it around more aggressively, to give
14787                // a good experience around switching between two apps.
14788                adj = ProcessList.PREVIOUS_APP_ADJ;
14789                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14790                app.cached = false;
14791                app.adjType = "previous";
14792            }
14793            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14794                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14795            }
14796        }
14797
14798        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14799                + " reason=" + app.adjType);
14800
14801        // By default, we use the computed adjustment.  It may be changed if
14802        // there are applications dependent on our services or providers, but
14803        // this gives us a baseline and makes sure we don't get into an
14804        // infinite recursion.
14805        app.adjSeq = mAdjSeq;
14806        app.curRawAdj = adj;
14807        app.hasStartedServices = false;
14808
14809        if (mBackupTarget != null && app == mBackupTarget.app) {
14810            // If possible we want to avoid killing apps while they're being backed up
14811            if (adj > ProcessList.BACKUP_APP_ADJ) {
14812                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14813                adj = ProcessList.BACKUP_APP_ADJ;
14814                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14815                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14816                }
14817                app.adjType = "backup";
14818                app.cached = false;
14819            }
14820            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14821                procState = ActivityManager.PROCESS_STATE_BACKUP;
14822            }
14823        }
14824
14825        boolean mayBeTop = false;
14826
14827        for (int is = app.services.size()-1;
14828                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14829                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14830                        || procState > ActivityManager.PROCESS_STATE_TOP);
14831                is--) {
14832            ServiceRecord s = app.services.valueAt(is);
14833            if (s.startRequested) {
14834                app.hasStartedServices = true;
14835                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14836                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14837                }
14838                if (app.hasShownUi && app != mHomeProcess) {
14839                    // If this process has shown some UI, let it immediately
14840                    // go to the LRU list because it may be pretty heavy with
14841                    // UI stuff.  We'll tag it with a label just to help
14842                    // debug and understand what is going on.
14843                    if (adj > ProcessList.SERVICE_ADJ) {
14844                        app.adjType = "cch-started-ui-services";
14845                    }
14846                } else {
14847                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14848                        // This service has seen some activity within
14849                        // recent memory, so we will keep its process ahead
14850                        // of the background processes.
14851                        if (adj > ProcessList.SERVICE_ADJ) {
14852                            adj = ProcessList.SERVICE_ADJ;
14853                            app.adjType = "started-services";
14854                            app.cached = false;
14855                        }
14856                    }
14857                    // If we have let the service slide into the background
14858                    // state, still have some text describing what it is doing
14859                    // even though the service no longer has an impact.
14860                    if (adj > ProcessList.SERVICE_ADJ) {
14861                        app.adjType = "cch-started-services";
14862                    }
14863                }
14864                // Don't kill this process because it is doing work; it
14865                // has said it is doing work.
14866                app.keeping = true;
14867            }
14868            for (int conni = s.connections.size()-1;
14869                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14870                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14871                            || procState > ActivityManager.PROCESS_STATE_TOP);
14872                    conni--) {
14873                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14874                for (int i = 0;
14875                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14876                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14877                                || procState > ActivityManager.PROCESS_STATE_TOP);
14878                        i++) {
14879                    // XXX should compute this based on the max of
14880                    // all connected clients.
14881                    ConnectionRecord cr = clist.get(i);
14882                    if (cr.binding.client == app) {
14883                        // Binding to ourself is not interesting.
14884                        continue;
14885                    }
14886                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14887                        ProcessRecord client = cr.binding.client;
14888                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14889                                TOP_APP, doingAll, now);
14890                        int clientProcState = client.curProcState;
14891                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14892                            // If the other app is cached for any reason, for purposes here
14893                            // we are going to consider it empty.  The specific cached state
14894                            // doesn't propagate except under certain conditions.
14895                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14896                        }
14897                        String adjType = null;
14898                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14899                            // Not doing bind OOM management, so treat
14900                            // this guy more like a started service.
14901                            if (app.hasShownUi && app != mHomeProcess) {
14902                                // If this process has shown some UI, let it immediately
14903                                // go to the LRU list because it may be pretty heavy with
14904                                // UI stuff.  We'll tag it with a label just to help
14905                                // debug and understand what is going on.
14906                                if (adj > clientAdj) {
14907                                    adjType = "cch-bound-ui-services";
14908                                }
14909                                app.cached = false;
14910                                clientAdj = adj;
14911                                clientProcState = procState;
14912                            } else {
14913                                if (now >= (s.lastActivity
14914                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14915                                    // This service has not seen activity within
14916                                    // recent memory, so allow it to drop to the
14917                                    // LRU list if there is no other reason to keep
14918                                    // it around.  We'll also tag it with a label just
14919                                    // to help debug and undertand what is going on.
14920                                    if (adj > clientAdj) {
14921                                        adjType = "cch-bound-services";
14922                                    }
14923                                    clientAdj = adj;
14924                                }
14925                            }
14926                        }
14927                        if (adj > clientAdj) {
14928                            // If this process has recently shown UI, and
14929                            // the process that is binding to it is less
14930                            // important than being visible, then we don't
14931                            // care about the binding as much as we care
14932                            // about letting this process get into the LRU
14933                            // list to be killed and restarted if needed for
14934                            // memory.
14935                            if (app.hasShownUi && app != mHomeProcess
14936                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14937                                adjType = "cch-bound-ui-services";
14938                            } else {
14939                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14940                                        |Context.BIND_IMPORTANT)) != 0) {
14941                                    adj = clientAdj;
14942                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14943                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14944                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14945                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14946                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14947                                    adj = clientAdj;
14948                                } else {
14949                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14950                                        adj = ProcessList.VISIBLE_APP_ADJ;
14951                                    }
14952                                }
14953                                if (!client.cached) {
14954                                    app.cached = false;
14955                                }
14956                                if (client.keeping) {
14957                                    app.keeping = true;
14958                                }
14959                                adjType = "service";
14960                            }
14961                        }
14962                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14963                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14964                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14965                            }
14966                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14967                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14968                                    // Special handling of clients who are in the top state.
14969                                    // We *may* want to consider this process to be in the
14970                                    // top state as well, but only if there is not another
14971                                    // reason for it to be running.  Being on the top is a
14972                                    // special state, meaning you are specifically running
14973                                    // for the current top app.  If the process is already
14974                                    // running in the background for some other reason, it
14975                                    // is more important to continue considering it to be
14976                                    // in the background state.
14977                                    mayBeTop = true;
14978                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14979                                } else {
14980                                    // Special handling for above-top states (persistent
14981                                    // processes).  These should not bring the current process
14982                                    // into the top state, since they are not on top.  Instead
14983                                    // give them the best state after that.
14984                                    clientProcState =
14985                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14986                                }
14987                            }
14988                        } else {
14989                            if (clientProcState <
14990                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14991                                clientProcState =
14992                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14993                            }
14994                        }
14995                        if (procState > clientProcState) {
14996                            procState = clientProcState;
14997                        }
14998                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14999                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15000                            app.pendingUiClean = true;
15001                        }
15002                        if (adjType != null) {
15003                            app.adjType = adjType;
15004                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15005                                    .REASON_SERVICE_IN_USE;
15006                            app.adjSource = cr.binding.client;
15007                            app.adjSourceOom = clientAdj;
15008                            app.adjTarget = s.name;
15009                        }
15010                    }
15011                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15012                        app.treatLikeActivity = true;
15013                    }
15014                    final ActivityRecord a = cr.activity;
15015                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15016                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15017                                (a.visible || a.state == ActivityState.RESUMED
15018                                 || a.state == ActivityState.PAUSING)) {
15019                            adj = ProcessList.FOREGROUND_APP_ADJ;
15020                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15021                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15022                            }
15023                            app.cached = false;
15024                            app.adjType = "service";
15025                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15026                                    .REASON_SERVICE_IN_USE;
15027                            app.adjSource = a;
15028                            app.adjSourceOom = adj;
15029                            app.adjTarget = s.name;
15030                        }
15031                    }
15032                }
15033            }
15034        }
15035
15036        for (int provi = app.pubProviders.size()-1;
15037                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15038                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15039                        || procState > ActivityManager.PROCESS_STATE_TOP);
15040                provi--) {
15041            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15042            for (int i = cpr.connections.size()-1;
15043                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15044                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15045                            || procState > ActivityManager.PROCESS_STATE_TOP);
15046                    i--) {
15047                ContentProviderConnection conn = cpr.connections.get(i);
15048                ProcessRecord client = conn.client;
15049                if (client == app) {
15050                    // Being our own client is not interesting.
15051                    continue;
15052                }
15053                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15054                int clientProcState = client.curProcState;
15055                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15056                    // If the other app is cached for any reason, for purposes here
15057                    // we are going to consider it empty.
15058                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15059                }
15060                if (adj > clientAdj) {
15061                    if (app.hasShownUi && app != mHomeProcess
15062                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15063                        app.adjType = "cch-ui-provider";
15064                    } else {
15065                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15066                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15067                        app.adjType = "provider";
15068                    }
15069                    app.cached &= client.cached;
15070                    app.keeping |= client.keeping;
15071                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15072                            .REASON_PROVIDER_IN_USE;
15073                    app.adjSource = client;
15074                    app.adjSourceOom = clientAdj;
15075                    app.adjTarget = cpr.name;
15076                }
15077                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15078                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15079                        // Special handling of clients who are in the top state.
15080                        // We *may* want to consider this process to be in the
15081                        // top state as well, but only if there is not another
15082                        // reason for it to be running.  Being on the top is a
15083                        // special state, meaning you are specifically running
15084                        // for the current top app.  If the process is already
15085                        // running in the background for some other reason, it
15086                        // is more important to continue considering it to be
15087                        // in the background state.
15088                        mayBeTop = true;
15089                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15090                    } else {
15091                        // Special handling for above-top states (persistent
15092                        // processes).  These should not bring the current process
15093                        // into the top state, since they are not on top.  Instead
15094                        // give them the best state after that.
15095                        clientProcState =
15096                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15097                    }
15098                }
15099                if (procState > clientProcState) {
15100                    procState = clientProcState;
15101                }
15102                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15103                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15104                }
15105            }
15106            // If the provider has external (non-framework) process
15107            // dependencies, ensure that its adjustment is at least
15108            // FOREGROUND_APP_ADJ.
15109            if (cpr.hasExternalProcessHandles()) {
15110                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15111                    adj = ProcessList.FOREGROUND_APP_ADJ;
15112                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15113                    app.cached = false;
15114                    app.keeping = true;
15115                    app.adjType = "provider";
15116                    app.adjTarget = cpr.name;
15117                }
15118                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15119                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15120                }
15121            }
15122        }
15123
15124        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15125            // A client of one of our services or providers is in the top state.  We
15126            // *may* want to be in the top state, but not if we are already running in
15127            // the background for some other reason.  For the decision here, we are going
15128            // to pick out a few specific states that we want to remain in when a client
15129            // is top (states that tend to be longer-term) and otherwise allow it to go
15130            // to the top state.
15131            switch (procState) {
15132                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15133                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15134                case ActivityManager.PROCESS_STATE_SERVICE:
15135                    // These all are longer-term states, so pull them up to the top
15136                    // of the background states, but not all the way to the top state.
15137                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15138                    break;
15139                default:
15140                    // Otherwise, top is a better choice, so take it.
15141                    procState = ActivityManager.PROCESS_STATE_TOP;
15142                    break;
15143            }
15144        }
15145
15146        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15147            if (app.hasClientActivities) {
15148                // This is a cached process, but with client activities.  Mark it so.
15149                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15150                app.adjType = "cch-client-act";
15151            } else if (app.treatLikeActivity) {
15152                // This is a cached process, but somebody wants us to treat it like it has
15153                // an activity, okay!
15154                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15155                app.adjType = "cch-as-act";
15156            }
15157        }
15158
15159        if (adj == ProcessList.SERVICE_ADJ) {
15160            if (doingAll) {
15161                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15162                mNewNumServiceProcs++;
15163                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15164                if (!app.serviceb) {
15165                    // This service isn't far enough down on the LRU list to
15166                    // normally be a B service, but if we are low on RAM and it
15167                    // is large we want to force it down since we would prefer to
15168                    // keep launcher over it.
15169                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15170                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15171                        app.serviceHighRam = true;
15172                        app.serviceb = true;
15173                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15174                    } else {
15175                        mNewNumAServiceProcs++;
15176                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15177                    }
15178                } else {
15179                    app.serviceHighRam = false;
15180                }
15181            }
15182            if (app.serviceb) {
15183                adj = ProcessList.SERVICE_B_ADJ;
15184            }
15185        }
15186
15187        app.curRawAdj = adj;
15188
15189        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15190        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15191        if (adj > app.maxAdj) {
15192            adj = app.maxAdj;
15193            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15194                schedGroup = Process.THREAD_GROUP_DEFAULT;
15195            }
15196        }
15197        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15198            app.keeping = true;
15199        }
15200
15201        // Do final modification to adj.  Everything we do between here and applying
15202        // the final setAdj must be done in this function, because we will also use
15203        // it when computing the final cached adj later.  Note that we don't need to
15204        // worry about this for max adj above, since max adj will always be used to
15205        // keep it out of the cached vaues.
15206        app.curAdj = app.modifyRawOomAdj(adj);
15207        app.curSchedGroup = schedGroup;
15208        app.curProcState = procState;
15209        app.foregroundActivities = foregroundActivities;
15210
15211        return app.curRawAdj;
15212    }
15213
15214    /**
15215     * Schedule PSS collection of a process.
15216     */
15217    void requestPssLocked(ProcessRecord proc, int procState) {
15218        if (mPendingPssProcesses.contains(proc)) {
15219            return;
15220        }
15221        if (mPendingPssProcesses.size() == 0) {
15222            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15223        }
15224        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15225        proc.pssProcState = procState;
15226        mPendingPssProcesses.add(proc);
15227    }
15228
15229    /**
15230     * Schedule PSS collection of all processes.
15231     */
15232    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15233        if (!always) {
15234            if (now < (mLastFullPssTime +
15235                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15236                return;
15237            }
15238        }
15239        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15240        mLastFullPssTime = now;
15241        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15242        mPendingPssProcesses.clear();
15243        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15244            ProcessRecord app = mLruProcesses.get(i);
15245            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15246                app.pssProcState = app.setProcState;
15247                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15248                        isSleeping(), now);
15249                mPendingPssProcesses.add(app);
15250            }
15251        }
15252        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15253    }
15254
15255    /**
15256     * Ask a given process to GC right now.
15257     */
15258    final void performAppGcLocked(ProcessRecord app) {
15259        try {
15260            app.lastRequestedGc = SystemClock.uptimeMillis();
15261            if (app.thread != null) {
15262                if (app.reportLowMemory) {
15263                    app.reportLowMemory = false;
15264                    app.thread.scheduleLowMemory();
15265                } else {
15266                    app.thread.processInBackground();
15267                }
15268            }
15269        } catch (Exception e) {
15270            // whatever.
15271        }
15272    }
15273
15274    /**
15275     * Returns true if things are idle enough to perform GCs.
15276     */
15277    private final boolean canGcNowLocked() {
15278        boolean processingBroadcasts = false;
15279        for (BroadcastQueue q : mBroadcastQueues) {
15280            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15281                processingBroadcasts = true;
15282            }
15283        }
15284        return !processingBroadcasts
15285                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15286    }
15287
15288    /**
15289     * Perform GCs on all processes that are waiting for it, but only
15290     * if things are idle.
15291     */
15292    final void performAppGcsLocked() {
15293        final int N = mProcessesToGc.size();
15294        if (N <= 0) {
15295            return;
15296        }
15297        if (canGcNowLocked()) {
15298            while (mProcessesToGc.size() > 0) {
15299                ProcessRecord proc = mProcessesToGc.remove(0);
15300                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15301                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15302                            <= SystemClock.uptimeMillis()) {
15303                        // To avoid spamming the system, we will GC processes one
15304                        // at a time, waiting a few seconds between each.
15305                        performAppGcLocked(proc);
15306                        scheduleAppGcsLocked();
15307                        return;
15308                    } else {
15309                        // It hasn't been long enough since we last GCed this
15310                        // process...  put it in the list to wait for its time.
15311                        addProcessToGcListLocked(proc);
15312                        break;
15313                    }
15314                }
15315            }
15316
15317            scheduleAppGcsLocked();
15318        }
15319    }
15320
15321    /**
15322     * If all looks good, perform GCs on all processes waiting for them.
15323     */
15324    final void performAppGcsIfAppropriateLocked() {
15325        if (canGcNowLocked()) {
15326            performAppGcsLocked();
15327            return;
15328        }
15329        // Still not idle, wait some more.
15330        scheduleAppGcsLocked();
15331    }
15332
15333    /**
15334     * Schedule the execution of all pending app GCs.
15335     */
15336    final void scheduleAppGcsLocked() {
15337        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15338
15339        if (mProcessesToGc.size() > 0) {
15340            // Schedule a GC for the time to the next process.
15341            ProcessRecord proc = mProcessesToGc.get(0);
15342            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15343
15344            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15345            long now = SystemClock.uptimeMillis();
15346            if (when < (now+GC_TIMEOUT)) {
15347                when = now + GC_TIMEOUT;
15348            }
15349            mHandler.sendMessageAtTime(msg, when);
15350        }
15351    }
15352
15353    /**
15354     * Add a process to the array of processes waiting to be GCed.  Keeps the
15355     * list in sorted order by the last GC time.  The process can't already be
15356     * on the list.
15357     */
15358    final void addProcessToGcListLocked(ProcessRecord proc) {
15359        boolean added = false;
15360        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15361            if (mProcessesToGc.get(i).lastRequestedGc <
15362                    proc.lastRequestedGc) {
15363                added = true;
15364                mProcessesToGc.add(i+1, proc);
15365                break;
15366            }
15367        }
15368        if (!added) {
15369            mProcessesToGc.add(0, proc);
15370        }
15371    }
15372
15373    /**
15374     * Set up to ask a process to GC itself.  This will either do it
15375     * immediately, or put it on the list of processes to gc the next
15376     * time things are idle.
15377     */
15378    final void scheduleAppGcLocked(ProcessRecord app) {
15379        long now = SystemClock.uptimeMillis();
15380        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15381            return;
15382        }
15383        if (!mProcessesToGc.contains(app)) {
15384            addProcessToGcListLocked(app);
15385            scheduleAppGcsLocked();
15386        }
15387    }
15388
15389    final void checkExcessivePowerUsageLocked(boolean doKills) {
15390        updateCpuStatsNow();
15391
15392        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15393        boolean doWakeKills = doKills;
15394        boolean doCpuKills = doKills;
15395        if (mLastPowerCheckRealtime == 0) {
15396            doWakeKills = false;
15397        }
15398        if (mLastPowerCheckUptime == 0) {
15399            doCpuKills = false;
15400        }
15401        if (stats.isScreenOn()) {
15402            doWakeKills = false;
15403        }
15404        final long curRealtime = SystemClock.elapsedRealtime();
15405        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15406        final long curUptime = SystemClock.uptimeMillis();
15407        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15408        mLastPowerCheckRealtime = curRealtime;
15409        mLastPowerCheckUptime = curUptime;
15410        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15411            doWakeKills = false;
15412        }
15413        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15414            doCpuKills = false;
15415        }
15416        int i = mLruProcesses.size();
15417        while (i > 0) {
15418            i--;
15419            ProcessRecord app = mLruProcesses.get(i);
15420            if (!app.keeping) {
15421                long wtime;
15422                synchronized (stats) {
15423                    wtime = stats.getProcessWakeTime(app.info.uid,
15424                            app.pid, curRealtime);
15425                }
15426                long wtimeUsed = wtime - app.lastWakeTime;
15427                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15428                if (DEBUG_POWER) {
15429                    StringBuilder sb = new StringBuilder(128);
15430                    sb.append("Wake for ");
15431                    app.toShortString(sb);
15432                    sb.append(": over ");
15433                    TimeUtils.formatDuration(realtimeSince, sb);
15434                    sb.append(" used ");
15435                    TimeUtils.formatDuration(wtimeUsed, sb);
15436                    sb.append(" (");
15437                    sb.append((wtimeUsed*100)/realtimeSince);
15438                    sb.append("%)");
15439                    Slog.i(TAG, sb.toString());
15440                    sb.setLength(0);
15441                    sb.append("CPU for ");
15442                    app.toShortString(sb);
15443                    sb.append(": over ");
15444                    TimeUtils.formatDuration(uptimeSince, sb);
15445                    sb.append(" used ");
15446                    TimeUtils.formatDuration(cputimeUsed, sb);
15447                    sb.append(" (");
15448                    sb.append((cputimeUsed*100)/uptimeSince);
15449                    sb.append("%)");
15450                    Slog.i(TAG, sb.toString());
15451                }
15452                // If a process has held a wake lock for more
15453                // than 50% of the time during this period,
15454                // that sounds bad.  Kill!
15455                if (doWakeKills && realtimeSince > 0
15456                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15457                    synchronized (stats) {
15458                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15459                                realtimeSince, wtimeUsed);
15460                    }
15461                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15462                            + " during " + realtimeSince);
15463                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15464                } else if (doCpuKills && uptimeSince > 0
15465                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15466                    synchronized (stats) {
15467                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15468                                uptimeSince, cputimeUsed);
15469                    }
15470                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15471                            + " during " + uptimeSince);
15472                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15473                } else {
15474                    app.lastWakeTime = wtime;
15475                    app.lastCpuTime = app.curCpuTime;
15476                }
15477            }
15478        }
15479    }
15480
15481    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15482            ProcessRecord TOP_APP, boolean doingAll, long now) {
15483        boolean success = true;
15484
15485        if (app.curRawAdj != app.setRawAdj) {
15486            if (wasKeeping && !app.keeping) {
15487                // This app is no longer something we want to keep.  Note
15488                // its current wake lock time to later know to kill it if
15489                // it is not behaving well.
15490                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15491                synchronized (stats) {
15492                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15493                            app.pid, SystemClock.elapsedRealtime());
15494                }
15495                app.lastCpuTime = app.curCpuTime;
15496            }
15497
15498            app.setRawAdj = app.curRawAdj;
15499        }
15500
15501        int changes = 0;
15502
15503        if (app.curAdj != app.setAdj) {
15504            ProcessList.setOomAdj(app.pid, app.curAdj);
15505            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15506                TAG, "Set " + app.pid + " " + app.processName +
15507                " adj " + app.curAdj + ": " + app.adjType);
15508            app.setAdj = app.curAdj;
15509        }
15510
15511        if (app.setSchedGroup != app.curSchedGroup) {
15512            app.setSchedGroup = app.curSchedGroup;
15513            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15514                    "Setting process group of " + app.processName
15515                    + " to " + app.curSchedGroup);
15516            if (app.waitingToKill != null &&
15517                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15518                killUnneededProcessLocked(app, app.waitingToKill);
15519                success = false;
15520            } else {
15521                if (true) {
15522                    long oldId = Binder.clearCallingIdentity();
15523                    try {
15524                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15525                    } catch (Exception e) {
15526                        Slog.w(TAG, "Failed setting process group of " + app.pid
15527                                + " to " + app.curSchedGroup);
15528                        e.printStackTrace();
15529                    } finally {
15530                        Binder.restoreCallingIdentity(oldId);
15531                    }
15532                } else {
15533                    if (app.thread != null) {
15534                        try {
15535                            app.thread.setSchedulingGroup(app.curSchedGroup);
15536                        } catch (RemoteException e) {
15537                        }
15538                    }
15539                }
15540                Process.setSwappiness(app.pid,
15541                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15542            }
15543        }
15544        if (app.repForegroundActivities != app.foregroundActivities) {
15545            app.repForegroundActivities = app.foregroundActivities;
15546            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15547        }
15548        if (app.repProcState != app.curProcState) {
15549            app.repProcState = app.curProcState;
15550            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15551            if (app.thread != null) {
15552                try {
15553                    if (false) {
15554                        //RuntimeException h = new RuntimeException("here");
15555                        Slog.i(TAG, "Sending new process state " + app.repProcState
15556                                + " to " + app /*, h*/);
15557                    }
15558                    app.thread.setProcessState(app.repProcState);
15559                } catch (RemoteException e) {
15560                }
15561            }
15562        }
15563        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15564                app.setProcState)) {
15565            app.lastStateTime = now;
15566            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15567                    isSleeping(), now);
15568            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15569                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15570                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15571                    + (app.nextPssTime-now) + ": " + app);
15572        } else {
15573            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15574                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15575                requestPssLocked(app, app.setProcState);
15576                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15577                        isSleeping(), now);
15578            } else if (false && DEBUG_PSS) {
15579                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15580            }
15581        }
15582        if (app.setProcState != app.curProcState) {
15583            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15584                    "Proc state change of " + app.processName
15585                    + " to " + app.curProcState);
15586            app.setProcState = app.curProcState;
15587            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15588                app.notCachedSinceIdle = false;
15589            }
15590            if (!doingAll) {
15591                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15592            } else {
15593                app.procStateChanged = true;
15594            }
15595        }
15596
15597        if (changes != 0) {
15598            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15599            int i = mPendingProcessChanges.size()-1;
15600            ProcessChangeItem item = null;
15601            while (i >= 0) {
15602                item = mPendingProcessChanges.get(i);
15603                if (item.pid == app.pid) {
15604                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15605                    break;
15606                }
15607                i--;
15608            }
15609            if (i < 0) {
15610                // No existing item in pending changes; need a new one.
15611                final int NA = mAvailProcessChanges.size();
15612                if (NA > 0) {
15613                    item = mAvailProcessChanges.remove(NA-1);
15614                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15615                } else {
15616                    item = new ProcessChangeItem();
15617                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15618                }
15619                item.changes = 0;
15620                item.pid = app.pid;
15621                item.uid = app.info.uid;
15622                if (mPendingProcessChanges.size() == 0) {
15623                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15624                            "*** Enqueueing dispatch processes changed!");
15625                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15626                }
15627                mPendingProcessChanges.add(item);
15628            }
15629            item.changes |= changes;
15630            item.processState = app.repProcState;
15631            item.foregroundActivities = app.repForegroundActivities;
15632            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15633                    + Integer.toHexString(System.identityHashCode(item))
15634                    + " " + app.toShortString() + ": changes=" + item.changes
15635                    + " procState=" + item.processState
15636                    + " foreground=" + item.foregroundActivities
15637                    + " type=" + app.adjType + " source=" + app.adjSource
15638                    + " target=" + app.adjTarget);
15639        }
15640
15641        return success;
15642    }
15643
15644    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15645        if (proc.thread != null && proc.baseProcessTracker != null) {
15646            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15647        }
15648    }
15649
15650    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15651            ProcessRecord TOP_APP, boolean doingAll, long now) {
15652        if (app.thread == null) {
15653            return false;
15654        }
15655
15656        final boolean wasKeeping = app.keeping;
15657
15658        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15659
15660        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15661    }
15662
15663    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15664            boolean oomAdj) {
15665        if (isForeground != proc.foregroundServices) {
15666            proc.foregroundServices = isForeground;
15667            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15668                    proc.info.uid);
15669            if (isForeground) {
15670                if (curProcs == null) {
15671                    curProcs = new ArrayList<ProcessRecord>();
15672                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15673                }
15674                if (!curProcs.contains(proc)) {
15675                    curProcs.add(proc);
15676                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15677                            proc.info.packageName, proc.info.uid);
15678                }
15679            } else {
15680                if (curProcs != null) {
15681                    if (curProcs.remove(proc)) {
15682                        mBatteryStatsService.noteEvent(
15683                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15684                                proc.info.packageName, proc.info.uid);
15685                        if (curProcs.size() <= 0) {
15686                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15687                        }
15688                    }
15689                }
15690            }
15691            if (oomAdj) {
15692                updateOomAdjLocked();
15693            }
15694        }
15695    }
15696
15697    private final ActivityRecord resumedAppLocked() {
15698        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15699        String pkg;
15700        int uid;
15701        if (act != null && !act.sleeping) {
15702            pkg = act.packageName;
15703            uid = act.info.applicationInfo.uid;
15704        } else {
15705            pkg = null;
15706            uid = -1;
15707        }
15708        // Has the UID or resumed package name changed?
15709        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15710                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15711            if (mCurResumedPackage != null) {
15712                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15713                        mCurResumedPackage, mCurResumedUid);
15714            }
15715            mCurResumedPackage = pkg;
15716            mCurResumedUid = uid;
15717            if (mCurResumedPackage != null) {
15718                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15719                        mCurResumedPackage, mCurResumedUid);
15720            }
15721        }
15722        return act;
15723    }
15724
15725    final boolean updateOomAdjLocked(ProcessRecord app) {
15726        final ActivityRecord TOP_ACT = resumedAppLocked();
15727        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15728        final boolean wasCached = app.cached;
15729
15730        mAdjSeq++;
15731
15732        // This is the desired cached adjusment we want to tell it to use.
15733        // If our app is currently cached, we know it, and that is it.  Otherwise,
15734        // we don't know it yet, and it needs to now be cached we will then
15735        // need to do a complete oom adj.
15736        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15737                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15738        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15739                SystemClock.uptimeMillis());
15740        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15741            // Changed to/from cached state, so apps after it in the LRU
15742            // list may also be changed.
15743            updateOomAdjLocked();
15744        }
15745        return success;
15746    }
15747
15748    final void updateOomAdjLocked() {
15749        final ActivityRecord TOP_ACT = resumedAppLocked();
15750        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15751        final long now = SystemClock.uptimeMillis();
15752        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15753        final int N = mLruProcesses.size();
15754
15755        if (false) {
15756            RuntimeException e = new RuntimeException();
15757            e.fillInStackTrace();
15758            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15759        }
15760
15761        mAdjSeq++;
15762        mNewNumServiceProcs = 0;
15763        mNewNumAServiceProcs = 0;
15764
15765        final int emptyProcessLimit;
15766        final int cachedProcessLimit;
15767        if (mProcessLimit <= 0) {
15768            emptyProcessLimit = cachedProcessLimit = 0;
15769        } else if (mProcessLimit == 1) {
15770            emptyProcessLimit = 1;
15771            cachedProcessLimit = 0;
15772        } else {
15773            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15774            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15775        }
15776
15777        // Let's determine how many processes we have running vs.
15778        // how many slots we have for background processes; we may want
15779        // to put multiple processes in a slot of there are enough of
15780        // them.
15781        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15782                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15783        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15784        if (numEmptyProcs > cachedProcessLimit) {
15785            // If there are more empty processes than our limit on cached
15786            // processes, then use the cached process limit for the factor.
15787            // This ensures that the really old empty processes get pushed
15788            // down to the bottom, so if we are running low on memory we will
15789            // have a better chance at keeping around more cached processes
15790            // instead of a gazillion empty processes.
15791            numEmptyProcs = cachedProcessLimit;
15792        }
15793        int emptyFactor = numEmptyProcs/numSlots;
15794        if (emptyFactor < 1) emptyFactor = 1;
15795        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15796        if (cachedFactor < 1) cachedFactor = 1;
15797        int stepCached = 0;
15798        int stepEmpty = 0;
15799        int numCached = 0;
15800        int numEmpty = 0;
15801        int numTrimming = 0;
15802
15803        mNumNonCachedProcs = 0;
15804        mNumCachedHiddenProcs = 0;
15805
15806        // First update the OOM adjustment for each of the
15807        // application processes based on their current state.
15808        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15809        int nextCachedAdj = curCachedAdj+1;
15810        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15811        int nextEmptyAdj = curEmptyAdj+2;
15812        for (int i=N-1; i>=0; i--) {
15813            ProcessRecord app = mLruProcesses.get(i);
15814            if (!app.killedByAm && app.thread != null) {
15815                app.procStateChanged = false;
15816                final boolean wasKeeping = app.keeping;
15817                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15818
15819                // If we haven't yet assigned the final cached adj
15820                // to the process, do that now.
15821                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15822                    switch (app.curProcState) {
15823                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15824                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15825                            // This process is a cached process holding activities...
15826                            // assign it the next cached value for that type, and then
15827                            // step that cached level.
15828                            app.curRawAdj = curCachedAdj;
15829                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15830                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15831                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15832                                    + ")");
15833                            if (curCachedAdj != nextCachedAdj) {
15834                                stepCached++;
15835                                if (stepCached >= cachedFactor) {
15836                                    stepCached = 0;
15837                                    curCachedAdj = nextCachedAdj;
15838                                    nextCachedAdj += 2;
15839                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15840                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15841                                    }
15842                                }
15843                            }
15844                            break;
15845                        default:
15846                            // For everything else, assign next empty cached process
15847                            // level and bump that up.  Note that this means that
15848                            // long-running services that have dropped down to the
15849                            // cached level will be treated as empty (since their process
15850                            // state is still as a service), which is what we want.
15851                            app.curRawAdj = curEmptyAdj;
15852                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15853                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15854                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15855                                    + ")");
15856                            if (curEmptyAdj != nextEmptyAdj) {
15857                                stepEmpty++;
15858                                if (stepEmpty >= emptyFactor) {
15859                                    stepEmpty = 0;
15860                                    curEmptyAdj = nextEmptyAdj;
15861                                    nextEmptyAdj += 2;
15862                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15863                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15864                                    }
15865                                }
15866                            }
15867                            break;
15868                    }
15869                }
15870
15871                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15872
15873                // Count the number of process types.
15874                switch (app.curProcState) {
15875                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15876                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15877                        mNumCachedHiddenProcs++;
15878                        numCached++;
15879                        if (numCached > cachedProcessLimit) {
15880                            killUnneededProcessLocked(app, "cached #" + numCached);
15881                        }
15882                        break;
15883                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15884                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15885                                && app.lastActivityTime < oldTime) {
15886                            killUnneededProcessLocked(app, "empty for "
15887                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15888                                    / 1000) + "s");
15889                        } else {
15890                            numEmpty++;
15891                            if (numEmpty > emptyProcessLimit) {
15892                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15893                            }
15894                        }
15895                        break;
15896                    default:
15897                        mNumNonCachedProcs++;
15898                        break;
15899                }
15900
15901                if (app.isolated && app.services.size() <= 0) {
15902                    // If this is an isolated process, and there are no
15903                    // services running in it, then the process is no longer
15904                    // needed.  We agressively kill these because we can by
15905                    // definition not re-use the same process again, and it is
15906                    // good to avoid having whatever code was running in them
15907                    // left sitting around after no longer needed.
15908                    killUnneededProcessLocked(app, "isolated not needed");
15909                }
15910
15911                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15912                        && !app.killedByAm) {
15913                    numTrimming++;
15914                }
15915            }
15916        }
15917
15918        mNumServiceProcs = mNewNumServiceProcs;
15919
15920        // Now determine the memory trimming level of background processes.
15921        // Unfortunately we need to start at the back of the list to do this
15922        // properly.  We only do this if the number of background apps we
15923        // are managing to keep around is less than half the maximum we desire;
15924        // if we are keeping a good number around, we'll let them use whatever
15925        // memory they want.
15926        final int numCachedAndEmpty = numCached + numEmpty;
15927        int memFactor;
15928        if (numCached <= ProcessList.TRIM_CACHED_APPS
15929                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15930            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15931                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15932            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15933                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15934            } else {
15935                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15936            }
15937        } else {
15938            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15939        }
15940        // We always allow the memory level to go up (better).  We only allow it to go
15941        // down if we are in a state where that is allowed, *and* the total number of processes
15942        // has gone down since last time.
15943        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15944                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15945                + " last=" + mLastNumProcesses);
15946        if (memFactor > mLastMemoryLevel) {
15947            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15948                memFactor = mLastMemoryLevel;
15949                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15950            }
15951        }
15952        mLastMemoryLevel = memFactor;
15953        mLastNumProcesses = mLruProcesses.size();
15954        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15955        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15956        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15957            if (mLowRamStartTime == 0) {
15958                mLowRamStartTime = now;
15959            }
15960            int step = 0;
15961            int fgTrimLevel;
15962            switch (memFactor) {
15963                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15964                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15965                    break;
15966                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15967                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15968                    break;
15969                default:
15970                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15971                    break;
15972            }
15973            int factor = numTrimming/3;
15974            int minFactor = 2;
15975            if (mHomeProcess != null) minFactor++;
15976            if (mPreviousProcess != null) minFactor++;
15977            if (factor < minFactor) factor = minFactor;
15978            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15979            for (int i=N-1; i>=0; i--) {
15980                ProcessRecord app = mLruProcesses.get(i);
15981                if (allChanged || app.procStateChanged) {
15982                    setProcessTrackerState(app, trackerMemFactor, now);
15983                    app.procStateChanged = false;
15984                }
15985                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15986                        && !app.killedByAm) {
15987                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15988                        try {
15989                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15990                                    "Trimming memory of " + app.processName
15991                                    + " to " + curLevel);
15992                            app.thread.scheduleTrimMemory(curLevel);
15993                        } catch (RemoteException e) {
15994                        }
15995                        if (false) {
15996                            // For now we won't do this; our memory trimming seems
15997                            // to be good enough at this point that destroying
15998                            // activities causes more harm than good.
15999                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16000                                    && app != mHomeProcess && app != mPreviousProcess) {
16001                                // Need to do this on its own message because the stack may not
16002                                // be in a consistent state at this point.
16003                                // For these apps we will also finish their activities
16004                                // to help them free memory.
16005                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16006                            }
16007                        }
16008                    }
16009                    app.trimMemoryLevel = curLevel;
16010                    step++;
16011                    if (step >= factor) {
16012                        step = 0;
16013                        switch (curLevel) {
16014                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16015                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16016                                break;
16017                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16018                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16019                                break;
16020                        }
16021                    }
16022                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16023                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16024                            && app.thread != null) {
16025                        try {
16026                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16027                                    "Trimming memory of heavy-weight " + app.processName
16028                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16029                            app.thread.scheduleTrimMemory(
16030                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16031                        } catch (RemoteException e) {
16032                        }
16033                    }
16034                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16035                } else {
16036                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16037                            || app.systemNoUi) && app.pendingUiClean) {
16038                        // If this application is now in the background and it
16039                        // had done UI, then give it the special trim level to
16040                        // have it free UI resources.
16041                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16042                        if (app.trimMemoryLevel < level && app.thread != null) {
16043                            try {
16044                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16045                                        "Trimming memory of bg-ui " + app.processName
16046                                        + " to " + level);
16047                                app.thread.scheduleTrimMemory(level);
16048                            } catch (RemoteException e) {
16049                            }
16050                        }
16051                        app.pendingUiClean = false;
16052                    }
16053                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16054                        try {
16055                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16056                                    "Trimming memory of fg " + app.processName
16057                                    + " to " + fgTrimLevel);
16058                            app.thread.scheduleTrimMemory(fgTrimLevel);
16059                        } catch (RemoteException e) {
16060                        }
16061                    }
16062                    app.trimMemoryLevel = fgTrimLevel;
16063                }
16064            }
16065        } else {
16066            if (mLowRamStartTime != 0) {
16067                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16068                mLowRamStartTime = 0;
16069            }
16070            for (int i=N-1; i>=0; i--) {
16071                ProcessRecord app = mLruProcesses.get(i);
16072                if (allChanged || app.procStateChanged) {
16073                    setProcessTrackerState(app, trackerMemFactor, now);
16074                    app.procStateChanged = false;
16075                }
16076                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16077                        || app.systemNoUi) && app.pendingUiClean) {
16078                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16079                            && app.thread != null) {
16080                        try {
16081                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16082                                    "Trimming memory of ui hidden " + app.processName
16083                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16084                            app.thread.scheduleTrimMemory(
16085                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16086                        } catch (RemoteException e) {
16087                        }
16088                    }
16089                    app.pendingUiClean = false;
16090                }
16091                app.trimMemoryLevel = 0;
16092            }
16093        }
16094
16095        if (mAlwaysFinishActivities) {
16096            // Need to do this on its own message because the stack may not
16097            // be in a consistent state at this point.
16098            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16099        }
16100
16101        if (allChanged) {
16102            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16103        }
16104
16105        if (mProcessStats.shouldWriteNowLocked(now)) {
16106            mHandler.post(new Runnable() {
16107                @Override public void run() {
16108                    synchronized (ActivityManagerService.this) {
16109                        mProcessStats.writeStateAsyncLocked();
16110                    }
16111                }
16112            });
16113        }
16114
16115        if (DEBUG_OOM_ADJ) {
16116            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16117        }
16118    }
16119
16120    final void trimApplications() {
16121        synchronized (this) {
16122            int i;
16123
16124            // First remove any unused application processes whose package
16125            // has been removed.
16126            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16127                final ProcessRecord app = mRemovedProcesses.get(i);
16128                if (app.activities.size() == 0
16129                        && app.curReceiver == null && app.services.size() == 0) {
16130                    Slog.i(
16131                        TAG, "Exiting empty application process "
16132                        + app.processName + " ("
16133                        + (app.thread != null ? app.thread.asBinder() : null)
16134                        + ")\n");
16135                    if (app.pid > 0 && app.pid != MY_PID) {
16136                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16137                                app.processName, app.setAdj, "empty");
16138                        app.killedByAm = true;
16139                        Process.killProcessQuiet(app.pid);
16140                    } else {
16141                        try {
16142                            app.thread.scheduleExit();
16143                        } catch (Exception e) {
16144                            // Ignore exceptions.
16145                        }
16146                    }
16147                    cleanUpApplicationRecordLocked(app, false, true, -1);
16148                    mRemovedProcesses.remove(i);
16149
16150                    if (app.persistent) {
16151                        if (app.persistent) {
16152                            addAppLocked(app.info, false);
16153                        }
16154                    }
16155                }
16156            }
16157
16158            // Now update the oom adj for all processes.
16159            updateOomAdjLocked();
16160        }
16161    }
16162
16163    /** This method sends the specified signal to each of the persistent apps */
16164    public void signalPersistentProcesses(int sig) throws RemoteException {
16165        if (sig != Process.SIGNAL_USR1) {
16166            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16167        }
16168
16169        synchronized (this) {
16170            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16171                    != PackageManager.PERMISSION_GRANTED) {
16172                throw new SecurityException("Requires permission "
16173                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16174            }
16175
16176            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16177                ProcessRecord r = mLruProcesses.get(i);
16178                if (r.thread != null && r.persistent) {
16179                    Process.sendSignal(r.pid, sig);
16180                }
16181            }
16182        }
16183    }
16184
16185    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16186        if (proc == null || proc == mProfileProc) {
16187            proc = mProfileProc;
16188            path = mProfileFile;
16189            profileType = mProfileType;
16190            clearProfilerLocked();
16191        }
16192        if (proc == null) {
16193            return;
16194        }
16195        try {
16196            proc.thread.profilerControl(false, path, null, profileType);
16197        } catch (RemoteException e) {
16198            throw new IllegalStateException("Process disappeared");
16199        }
16200    }
16201
16202    private void clearProfilerLocked() {
16203        if (mProfileFd != null) {
16204            try {
16205                mProfileFd.close();
16206            } catch (IOException e) {
16207            }
16208        }
16209        mProfileApp = null;
16210        mProfileProc = null;
16211        mProfileFile = null;
16212        mProfileType = 0;
16213        mAutoStopProfiler = false;
16214    }
16215
16216    public boolean profileControl(String process, int userId, boolean start,
16217            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16218
16219        try {
16220            synchronized (this) {
16221                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16222                // its own permission.
16223                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16224                        != PackageManager.PERMISSION_GRANTED) {
16225                    throw new SecurityException("Requires permission "
16226                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16227                }
16228
16229                if (start && fd == null) {
16230                    throw new IllegalArgumentException("null fd");
16231                }
16232
16233                ProcessRecord proc = null;
16234                if (process != null) {
16235                    proc = findProcessLocked(process, userId, "profileControl");
16236                }
16237
16238                if (start && (proc == null || proc.thread == null)) {
16239                    throw new IllegalArgumentException("Unknown process: " + process);
16240                }
16241
16242                if (start) {
16243                    stopProfilerLocked(null, null, 0);
16244                    setProfileApp(proc.info, proc.processName, path, fd, false);
16245                    mProfileProc = proc;
16246                    mProfileType = profileType;
16247                    try {
16248                        fd = fd.dup();
16249                    } catch (IOException e) {
16250                        fd = null;
16251                    }
16252                    proc.thread.profilerControl(start, path, fd, profileType);
16253                    fd = null;
16254                    mProfileFd = null;
16255                } else {
16256                    stopProfilerLocked(proc, path, profileType);
16257                    if (fd != null) {
16258                        try {
16259                            fd.close();
16260                        } catch (IOException e) {
16261                        }
16262                    }
16263                }
16264
16265                return true;
16266            }
16267        } catch (RemoteException e) {
16268            throw new IllegalStateException("Process disappeared");
16269        } finally {
16270            if (fd != null) {
16271                try {
16272                    fd.close();
16273                } catch (IOException e) {
16274                }
16275            }
16276        }
16277    }
16278
16279    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16281                userId, true, true, callName, null);
16282        ProcessRecord proc = null;
16283        try {
16284            int pid = Integer.parseInt(process);
16285            synchronized (mPidsSelfLocked) {
16286                proc = mPidsSelfLocked.get(pid);
16287            }
16288        } catch (NumberFormatException e) {
16289        }
16290
16291        if (proc == null) {
16292            ArrayMap<String, SparseArray<ProcessRecord>> all
16293                    = mProcessNames.getMap();
16294            SparseArray<ProcessRecord> procs = all.get(process);
16295            if (procs != null && procs.size() > 0) {
16296                proc = procs.valueAt(0);
16297                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16298                    for (int i=1; i<procs.size(); i++) {
16299                        ProcessRecord thisProc = procs.valueAt(i);
16300                        if (thisProc.userId == userId) {
16301                            proc = thisProc;
16302                            break;
16303                        }
16304                    }
16305                }
16306            }
16307        }
16308
16309        return proc;
16310    }
16311
16312    public boolean dumpHeap(String process, int userId, boolean managed,
16313            String path, ParcelFileDescriptor fd) throws RemoteException {
16314
16315        try {
16316            synchronized (this) {
16317                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16318                // its own permission (same as profileControl).
16319                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16320                        != PackageManager.PERMISSION_GRANTED) {
16321                    throw new SecurityException("Requires permission "
16322                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16323                }
16324
16325                if (fd == null) {
16326                    throw new IllegalArgumentException("null fd");
16327                }
16328
16329                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16330                if (proc == null || proc.thread == null) {
16331                    throw new IllegalArgumentException("Unknown process: " + process);
16332                }
16333
16334                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16335                if (!isDebuggable) {
16336                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16337                        throw new SecurityException("Process not debuggable: " + proc);
16338                    }
16339                }
16340
16341                proc.thread.dumpHeap(managed, path, fd);
16342                fd = null;
16343                return true;
16344            }
16345        } catch (RemoteException e) {
16346            throw new IllegalStateException("Process disappeared");
16347        } finally {
16348            if (fd != null) {
16349                try {
16350                    fd.close();
16351                } catch (IOException e) {
16352                }
16353            }
16354        }
16355    }
16356
16357    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16358    public void monitor() {
16359        synchronized (this) { }
16360    }
16361
16362    void onCoreSettingsChange(Bundle settings) {
16363        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16364            ProcessRecord processRecord = mLruProcesses.get(i);
16365            try {
16366                if (processRecord.thread != null) {
16367                    processRecord.thread.setCoreSettings(settings);
16368                }
16369            } catch (RemoteException re) {
16370                /* ignore */
16371            }
16372        }
16373    }
16374
16375    // Multi-user methods
16376
16377    /**
16378     * Start user, if its not already running, but don't bring it to foreground.
16379     */
16380    @Override
16381    public boolean startUserInBackground(final int userId) {
16382        return startUser(userId, /* foreground */ false);
16383    }
16384
16385    /**
16386     * Refreshes the list of users related to the current user when either a
16387     * user switch happens or when a new related user is started in the
16388     * background.
16389     */
16390    private void updateCurrentProfileIdsLocked() {
16391        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16392                mCurrentUserId, false /* enabledOnly */);
16393        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16394        for (int i = 0; i < currentProfileIds.length; i++) {
16395            currentProfileIds[i] = profiles.get(i).id;
16396        }
16397        mCurrentProfileIds = currentProfileIds;
16398    }
16399
16400    private Set getProfileIdsLocked(int userId) {
16401        Set userIds = new HashSet<Integer>();
16402        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16403                userId, false /* enabledOnly */);
16404        for (UserInfo user : profiles) {
16405            userIds.add(Integer.valueOf(user.id));
16406        }
16407        return userIds;
16408    }
16409
16410    @Override
16411    public boolean switchUser(final int userId) {
16412        return startUser(userId, /* foregound */ true);
16413    }
16414
16415    private boolean startUser(final int userId, boolean foreground) {
16416        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16417                != PackageManager.PERMISSION_GRANTED) {
16418            String msg = "Permission Denial: switchUser() from pid="
16419                    + Binder.getCallingPid()
16420                    + ", uid=" + Binder.getCallingUid()
16421                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16422            Slog.w(TAG, msg);
16423            throw new SecurityException(msg);
16424        }
16425
16426        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16427
16428        final long ident = Binder.clearCallingIdentity();
16429        try {
16430            synchronized (this) {
16431                final int oldUserId = mCurrentUserId;
16432                if (oldUserId == userId) {
16433                    return true;
16434                }
16435
16436                mStackSupervisor.setLockTaskModeLocked(null);
16437
16438                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16439                if (userInfo == null) {
16440                    Slog.w(TAG, "No user info for user #" + userId);
16441                    return false;
16442                }
16443
16444                if (foreground) {
16445                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16446                            R.anim.screen_user_enter);
16447                }
16448
16449                boolean needStart = false;
16450
16451                // If the user we are switching to is not currently started, then
16452                // we need to start it now.
16453                if (mStartedUsers.get(userId) == null) {
16454                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16455                    updateStartedUserArrayLocked();
16456                    needStart = true;
16457                }
16458
16459                final Integer userIdInt = Integer.valueOf(userId);
16460                mUserLru.remove(userIdInt);
16461                mUserLru.add(userIdInt);
16462
16463                if (foreground) {
16464                    mCurrentUserId = userId;
16465                    updateCurrentProfileIdsLocked();
16466                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16467                    // Once the internal notion of the active user has switched, we lock the device
16468                    // with the option to show the user switcher on the keyguard.
16469                    mWindowManager.lockNow(null);
16470                } else {
16471                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16472                    updateCurrentProfileIdsLocked();
16473                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16474                    mUserLru.remove(currentUserIdInt);
16475                    mUserLru.add(currentUserIdInt);
16476                }
16477
16478                final UserStartedState uss = mStartedUsers.get(userId);
16479
16480                // Make sure user is in the started state.  If it is currently
16481                // stopping, we need to knock that off.
16482                if (uss.mState == UserStartedState.STATE_STOPPING) {
16483                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16484                    // so we can just fairly silently bring the user back from
16485                    // the almost-dead.
16486                    uss.mState = UserStartedState.STATE_RUNNING;
16487                    updateStartedUserArrayLocked();
16488                    needStart = true;
16489                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16490                    // This means ACTION_SHUTDOWN has been sent, so we will
16491                    // need to treat this as a new boot of the user.
16492                    uss.mState = UserStartedState.STATE_BOOTING;
16493                    updateStartedUserArrayLocked();
16494                    needStart = true;
16495                }
16496
16497                if (uss.mState == UserStartedState.STATE_BOOTING) {
16498                    // Booting up a new user, need to tell system services about it.
16499                    // Note that this is on the same handler as scheduling of broadcasts,
16500                    // which is important because it needs to go first.
16501                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16502                }
16503
16504                if (foreground) {
16505                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16506                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16507                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16508                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16509                            oldUserId, userId, uss));
16510                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16511                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16512                }
16513
16514                if (needStart) {
16515                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16516                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16517                            | Intent.FLAG_RECEIVER_FOREGROUND);
16518                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16519                    broadcastIntentLocked(null, null, intent,
16520                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16521                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16522                }
16523
16524                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16525                    if (userId != 0) {
16526                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16527                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16528                        broadcastIntentLocked(null, null, intent, null,
16529                                new IIntentReceiver.Stub() {
16530                                    public void performReceive(Intent intent, int resultCode,
16531                                            String data, Bundle extras, boolean ordered,
16532                                            boolean sticky, int sendingUser) {
16533                                        userInitialized(uss, userId);
16534                                    }
16535                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16536                                true, false, MY_PID, Process.SYSTEM_UID,
16537                                userId);
16538                        uss.initializing = true;
16539                    } else {
16540                        getUserManagerLocked().makeInitialized(userInfo.id);
16541                    }
16542                }
16543
16544                if (foreground) {
16545                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16546                    if (homeInFront) {
16547                        startHomeActivityLocked(userId);
16548                    } else {
16549                        mStackSupervisor.resumeTopActivitiesLocked();
16550                    }
16551                    EventLogTags.writeAmSwitchUser(userId);
16552                    getUserManagerLocked().userForeground(userId);
16553                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16554                }
16555
16556                if (needStart) {
16557                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16558                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16559                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16560                    broadcastIntentLocked(null, null, intent,
16561                            null, new IIntentReceiver.Stub() {
16562                                @Override
16563                                public void performReceive(Intent intent, int resultCode, String data,
16564                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16565                                        throws RemoteException {
16566                                }
16567                            }, 0, null, null,
16568                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16569                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16570                }
16571            }
16572        } finally {
16573            Binder.restoreCallingIdentity(ident);
16574        }
16575
16576        return true;
16577    }
16578
16579    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16580        long ident = Binder.clearCallingIdentity();
16581        try {
16582            Intent intent;
16583            if (oldUserId >= 0) {
16584                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16585                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16586                        | Intent.FLAG_RECEIVER_FOREGROUND);
16587                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16588                broadcastIntentLocked(null, null, intent,
16589                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16590                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16591            }
16592            if (newUserId >= 0) {
16593                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16594                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16595                        | Intent.FLAG_RECEIVER_FOREGROUND);
16596                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16597                broadcastIntentLocked(null, null, intent,
16598                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16599                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16600                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16601                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16602                        | Intent.FLAG_RECEIVER_FOREGROUND);
16603                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16604                broadcastIntentLocked(null, null, intent,
16605                        null, null, 0, null, null,
16606                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16607                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16608            }
16609        } finally {
16610            Binder.restoreCallingIdentity(ident);
16611        }
16612    }
16613
16614    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16615            final int newUserId) {
16616        final int N = mUserSwitchObservers.beginBroadcast();
16617        if (N > 0) {
16618            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16619                int mCount = 0;
16620                @Override
16621                public void sendResult(Bundle data) throws RemoteException {
16622                    synchronized (ActivityManagerService.this) {
16623                        if (mCurUserSwitchCallback == this) {
16624                            mCount++;
16625                            if (mCount == N) {
16626                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16627                            }
16628                        }
16629                    }
16630                }
16631            };
16632            synchronized (this) {
16633                uss.switching = true;
16634                mCurUserSwitchCallback = callback;
16635            }
16636            for (int i=0; i<N; i++) {
16637                try {
16638                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16639                            newUserId, callback);
16640                } catch (RemoteException e) {
16641                }
16642            }
16643        } else {
16644            synchronized (this) {
16645                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16646            }
16647        }
16648        mUserSwitchObservers.finishBroadcast();
16649    }
16650
16651    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16652        synchronized (this) {
16653            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16654            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16655        }
16656    }
16657
16658    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16659        mCurUserSwitchCallback = null;
16660        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16661        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16662                oldUserId, newUserId, uss));
16663    }
16664
16665    void userInitialized(UserStartedState uss, int newUserId) {
16666        completeSwitchAndInitalize(uss, newUserId, true, false);
16667    }
16668
16669    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16670        completeSwitchAndInitalize(uss, newUserId, false, true);
16671    }
16672
16673    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16674            boolean clearInitializing, boolean clearSwitching) {
16675        boolean unfrozen = false;
16676        synchronized (this) {
16677            if (clearInitializing) {
16678                uss.initializing = false;
16679                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16680            }
16681            if (clearSwitching) {
16682                uss.switching = false;
16683            }
16684            if (!uss.switching && !uss.initializing) {
16685                mWindowManager.stopFreezingScreen();
16686                unfrozen = true;
16687            }
16688        }
16689        if (unfrozen) {
16690            final int N = mUserSwitchObservers.beginBroadcast();
16691            for (int i=0; i<N; i++) {
16692                try {
16693                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16694                } catch (RemoteException e) {
16695                }
16696            }
16697            mUserSwitchObservers.finishBroadcast();
16698        }
16699    }
16700
16701    void scheduleStartProfilesLocked() {
16702        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16703            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16704                    DateUtils.SECOND_IN_MILLIS);
16705        }
16706    }
16707
16708    void startProfilesLocked() {
16709        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16710        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16711                mCurrentUserId, false /* enabledOnly */);
16712        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16713        for (UserInfo user : profiles) {
16714            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16715                    && user.id != mCurrentUserId) {
16716                toStart.add(user);
16717            }
16718        }
16719        final int n = toStart.size();
16720        int i = 0;
16721        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16722            startUserInBackground(toStart.get(i).id);
16723        }
16724        if (i < n) {
16725            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16726        }
16727    }
16728
16729    void finishUserSwitch(UserStartedState uss) {
16730        synchronized (this) {
16731            if (uss.mState == UserStartedState.STATE_BOOTING
16732                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16733                uss.mState = UserStartedState.STATE_RUNNING;
16734                final int userId = uss.mHandle.getIdentifier();
16735                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16736                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16737                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16738                broadcastIntentLocked(null, null, intent,
16739                        null, null, 0, null, null,
16740                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16741                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16742            }
16743
16744            startProfilesLocked();
16745
16746            int num = mUserLru.size();
16747            int i = 0;
16748            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16749                Integer oldUserId = mUserLru.get(i);
16750                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16751                if (oldUss == null) {
16752                    // Shouldn't happen, but be sane if it does.
16753                    mUserLru.remove(i);
16754                    num--;
16755                    continue;
16756                }
16757                if (oldUss.mState == UserStartedState.STATE_STOPPING
16758                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16759                    // This user is already stopping, doesn't count.
16760                    num--;
16761                    i++;
16762                    continue;
16763                }
16764                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16765                    // Owner and current can't be stopped, but count as running.
16766                    i++;
16767                    continue;
16768                }
16769                // This is a user to be stopped.
16770                stopUserLocked(oldUserId, null);
16771                num--;
16772                i++;
16773            }
16774        }
16775    }
16776
16777    @Override
16778    public int stopUser(final int userId, final IStopUserCallback callback) {
16779        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16780                != PackageManager.PERMISSION_GRANTED) {
16781            String msg = "Permission Denial: switchUser() from pid="
16782                    + Binder.getCallingPid()
16783                    + ", uid=" + Binder.getCallingUid()
16784                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16785            Slog.w(TAG, msg);
16786            throw new SecurityException(msg);
16787        }
16788        if (userId <= 0) {
16789            throw new IllegalArgumentException("Can't stop primary user " + userId);
16790        }
16791        synchronized (this) {
16792            return stopUserLocked(userId, callback);
16793        }
16794    }
16795
16796    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16797        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16798        if (mCurrentUserId == userId) {
16799            return ActivityManager.USER_OP_IS_CURRENT;
16800        }
16801
16802        final UserStartedState uss = mStartedUsers.get(userId);
16803        if (uss == null) {
16804            // User is not started, nothing to do...  but we do need to
16805            // callback if requested.
16806            if (callback != null) {
16807                mHandler.post(new Runnable() {
16808                    @Override
16809                    public void run() {
16810                        try {
16811                            callback.userStopped(userId);
16812                        } catch (RemoteException e) {
16813                        }
16814                    }
16815                });
16816            }
16817            return ActivityManager.USER_OP_SUCCESS;
16818        }
16819
16820        if (callback != null) {
16821            uss.mStopCallbacks.add(callback);
16822        }
16823
16824        if (uss.mState != UserStartedState.STATE_STOPPING
16825                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16826            uss.mState = UserStartedState.STATE_STOPPING;
16827            updateStartedUserArrayLocked();
16828
16829            long ident = Binder.clearCallingIdentity();
16830            try {
16831                // We are going to broadcast ACTION_USER_STOPPING and then
16832                // once that is done send a final ACTION_SHUTDOWN and then
16833                // stop the user.
16834                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16835                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16836                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16837                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16838                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16839                // This is the result receiver for the final shutdown broadcast.
16840                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16841                    @Override
16842                    public void performReceive(Intent intent, int resultCode, String data,
16843                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16844                        finishUserStop(uss);
16845                    }
16846                };
16847                // This is the result receiver for the initial stopping broadcast.
16848                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16849                    @Override
16850                    public void performReceive(Intent intent, int resultCode, String data,
16851                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16852                        // On to the next.
16853                        synchronized (ActivityManagerService.this) {
16854                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16855                                // Whoops, we are being started back up.  Abort, abort!
16856                                return;
16857                            }
16858                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16859                        }
16860                        mSystemServiceManager.stopUser(userId);
16861                        broadcastIntentLocked(null, null, shutdownIntent,
16862                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16863                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16864                    }
16865                };
16866                // Kick things off.
16867                broadcastIntentLocked(null, null, stoppingIntent,
16868                        null, stoppingReceiver, 0, null, null,
16869                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16870                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16871            } finally {
16872                Binder.restoreCallingIdentity(ident);
16873            }
16874        }
16875
16876        return ActivityManager.USER_OP_SUCCESS;
16877    }
16878
16879    void finishUserStop(UserStartedState uss) {
16880        final int userId = uss.mHandle.getIdentifier();
16881        boolean stopped;
16882        ArrayList<IStopUserCallback> callbacks;
16883        synchronized (this) {
16884            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16885            if (mStartedUsers.get(userId) != uss) {
16886                stopped = false;
16887            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16888                stopped = false;
16889            } else {
16890                stopped = true;
16891                // User can no longer run.
16892                mStartedUsers.remove(userId);
16893                mUserLru.remove(Integer.valueOf(userId));
16894                updateStartedUserArrayLocked();
16895
16896                // Clean up all state and processes associated with the user.
16897                // Kill all the processes for the user.
16898                forceStopUserLocked(userId, "finish user");
16899            }
16900        }
16901
16902        for (int i=0; i<callbacks.size(); i++) {
16903            try {
16904                if (stopped) callbacks.get(i).userStopped(userId);
16905                else callbacks.get(i).userStopAborted(userId);
16906            } catch (RemoteException e) {
16907            }
16908        }
16909
16910        if (stopped) {
16911            mSystemServiceManager.cleanupUser(userId);
16912            synchronized (this) {
16913                mStackSupervisor.removeUserLocked(userId);
16914            }
16915        }
16916    }
16917
16918    @Override
16919    public UserInfo getCurrentUser() {
16920        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16921                != PackageManager.PERMISSION_GRANTED) && (
16922                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16923                != PackageManager.PERMISSION_GRANTED)) {
16924            String msg = "Permission Denial: getCurrentUser() from pid="
16925                    + Binder.getCallingPid()
16926                    + ", uid=" + Binder.getCallingUid()
16927                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16928            Slog.w(TAG, msg);
16929            throw new SecurityException(msg);
16930        }
16931        synchronized (this) {
16932            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16933        }
16934    }
16935
16936    int getCurrentUserIdLocked() {
16937        return mCurrentUserId;
16938    }
16939
16940    @Override
16941    public boolean isUserRunning(int userId, boolean orStopped) {
16942        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16943                != PackageManager.PERMISSION_GRANTED) {
16944            String msg = "Permission Denial: isUserRunning() from pid="
16945                    + Binder.getCallingPid()
16946                    + ", uid=" + Binder.getCallingUid()
16947                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16948            Slog.w(TAG, msg);
16949            throw new SecurityException(msg);
16950        }
16951        synchronized (this) {
16952            return isUserRunningLocked(userId, orStopped);
16953        }
16954    }
16955
16956    boolean isUserRunningLocked(int userId, boolean orStopped) {
16957        UserStartedState state = mStartedUsers.get(userId);
16958        if (state == null) {
16959            return false;
16960        }
16961        if (orStopped) {
16962            return true;
16963        }
16964        return state.mState != UserStartedState.STATE_STOPPING
16965                && state.mState != UserStartedState.STATE_SHUTDOWN;
16966    }
16967
16968    @Override
16969    public int[] getRunningUserIds() {
16970        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16971                != PackageManager.PERMISSION_GRANTED) {
16972            String msg = "Permission Denial: isUserRunning() from pid="
16973                    + Binder.getCallingPid()
16974                    + ", uid=" + Binder.getCallingUid()
16975                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16976            Slog.w(TAG, msg);
16977            throw new SecurityException(msg);
16978        }
16979        synchronized (this) {
16980            return mStartedUserArray;
16981        }
16982    }
16983
16984    private void updateStartedUserArrayLocked() {
16985        int num = 0;
16986        for (int i=0; i<mStartedUsers.size();  i++) {
16987            UserStartedState uss = mStartedUsers.valueAt(i);
16988            // This list does not include stopping users.
16989            if (uss.mState != UserStartedState.STATE_STOPPING
16990                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16991                num++;
16992            }
16993        }
16994        mStartedUserArray = new int[num];
16995        num = 0;
16996        for (int i=0; i<mStartedUsers.size();  i++) {
16997            UserStartedState uss = mStartedUsers.valueAt(i);
16998            if (uss.mState != UserStartedState.STATE_STOPPING
16999                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17000                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17001                num++;
17002            }
17003        }
17004    }
17005
17006    @Override
17007    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17008        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17009                != PackageManager.PERMISSION_GRANTED) {
17010            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17011                    + Binder.getCallingPid()
17012                    + ", uid=" + Binder.getCallingUid()
17013                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17014            Slog.w(TAG, msg);
17015            throw new SecurityException(msg);
17016        }
17017
17018        mUserSwitchObservers.register(observer);
17019    }
17020
17021    @Override
17022    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17023        mUserSwitchObservers.unregister(observer);
17024    }
17025
17026    private boolean userExists(int userId) {
17027        if (userId == 0) {
17028            return true;
17029        }
17030        UserManagerService ums = getUserManagerLocked();
17031        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17032    }
17033
17034    int[] getUsersLocked() {
17035        UserManagerService ums = getUserManagerLocked();
17036        return ums != null ? ums.getUserIds() : new int[] { 0 };
17037    }
17038
17039    UserManagerService getUserManagerLocked() {
17040        if (mUserManager == null) {
17041            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17042            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17043        }
17044        return mUserManager;
17045    }
17046
17047    private int applyUserId(int uid, int userId) {
17048        return UserHandle.getUid(userId, uid);
17049    }
17050
17051    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17052        if (info == null) return null;
17053        ApplicationInfo newInfo = new ApplicationInfo(info);
17054        newInfo.uid = applyUserId(info.uid, userId);
17055        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17056                + info.packageName;
17057        return newInfo;
17058    }
17059
17060    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17061        if (aInfo == null
17062                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17063            return aInfo;
17064        }
17065
17066        ActivityInfo info = new ActivityInfo(aInfo);
17067        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17068        return info;
17069    }
17070
17071    private final class LocalService extends ActivityManagerInternal {
17072        @Override
17073        public void goingToSleep() {
17074            ActivityManagerService.this.goingToSleep();
17075        }
17076
17077        @Override
17078        public void wakingUp() {
17079            ActivityManagerService.this.wakingUp();
17080        }
17081    }
17082}
17083