ActivityManagerService.java revision 09233289624a85093b1d99e4a6a149bf09059d8d
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 = Math.min(numActivities, 1); activityNdx < numActivities;
7074                            ++activityNdx) {
7075                        final ActivityRecord r = activities.get(activityNdx);
7076                        if (r.intent != null &&
7077                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7078                                        != 0) {
7079                            break;
7080                        }
7081                    }
7082                    // Traverse downwards starting below break looking for set label and icon.
7083                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7084                        final ActivityRecord r = activities.get(activityNdx);
7085                        if (r.activityLabel != null || r.activityIcon != null) {
7086                            rti.activityLabel = r.activityLabel;
7087                            rti.activityIcon = r.activityIcon;
7088                            break;
7089                        }
7090                    }
7091
7092                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7093                        // Check whether this activity is currently available.
7094                        try {
7095                            if (rti.origActivity != null) {
7096                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7097                                        == null) {
7098                                    continue;
7099                                }
7100                            } else if (rti.baseIntent != null) {
7101                                if (pm.queryIntentActivities(rti.baseIntent,
7102                                        null, 0, userId) == null) {
7103                                    continue;
7104                                }
7105                            }
7106                        } catch (RemoteException e) {
7107                            // Will never happen.
7108                        }
7109                    }
7110
7111                    res.add(rti);
7112                    maxNum--;
7113                }
7114            }
7115            return res;
7116        }
7117    }
7118
7119    private TaskRecord recentTaskForIdLocked(int id) {
7120        final int N = mRecentTasks.size();
7121            for (int i=0; i<N; i++) {
7122                TaskRecord tr = mRecentTasks.get(i);
7123                if (tr.taskId == id) {
7124                    return tr;
7125                }
7126            }
7127            return null;
7128    }
7129
7130    @Override
7131    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7132        synchronized (this) {
7133            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7134                    "getTaskThumbnails()");
7135            TaskRecord tr = recentTaskForIdLocked(id);
7136            if (tr != null) {
7137                return tr.getTaskThumbnailsLocked();
7138            }
7139        }
7140        return null;
7141    }
7142
7143    @Override
7144    public Bitmap getTaskTopThumbnail(int id) {
7145        synchronized (this) {
7146            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7147                    "getTaskTopThumbnail()");
7148            TaskRecord tr = recentTaskForIdLocked(id);
7149            if (tr != null) {
7150                return tr.getTaskTopThumbnailLocked();
7151            }
7152        }
7153        return null;
7154    }
7155
7156    @Override
7157    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7158            Bitmap activityIcon) {
7159        synchronized (this) {
7160            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7161            if (r != null) {
7162                r.activityLabel = activityLabel.toString();
7163                r.activityIcon = activityIcon;
7164            }
7165        }
7166    }
7167
7168    @Override
7169    public boolean removeSubTask(int taskId, int subTaskIndex) {
7170        synchronized (this) {
7171            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7172                    "removeSubTask()");
7173            long ident = Binder.clearCallingIdentity();
7174            try {
7175                TaskRecord tr = recentTaskForIdLocked(taskId);
7176                if (tr != null) {
7177                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7178                }
7179                return false;
7180            } finally {
7181                Binder.restoreCallingIdentity(ident);
7182            }
7183        }
7184    }
7185
7186    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7187        if (!pr.killedByAm) {
7188            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7189            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7190                    pr.processName, pr.setAdj, reason);
7191            pr.killedByAm = true;
7192            Process.killProcessQuiet(pr.pid);
7193        }
7194    }
7195
7196    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7197        tr.disposeThumbnail();
7198        mRecentTasks.remove(tr);
7199        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7200        Intent baseIntent = new Intent(
7201                tr.intent != null ? tr.intent : tr.affinityIntent);
7202        ComponentName component = baseIntent.getComponent();
7203        if (component == null) {
7204            Slog.w(TAG, "Now component for base intent of task: " + tr);
7205            return;
7206        }
7207
7208        // Find any running services associated with this app.
7209        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7210
7211        if (killProcesses) {
7212            // Find any running processes associated with this app.
7213            final String pkg = component.getPackageName();
7214            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7215            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7216            for (int i=0; i<pmap.size(); i++) {
7217                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7218                for (int j=0; j<uids.size(); j++) {
7219                    ProcessRecord proc = uids.valueAt(j);
7220                    if (proc.userId != tr.userId) {
7221                        continue;
7222                    }
7223                    if (!proc.pkgList.containsKey(pkg)) {
7224                        continue;
7225                    }
7226                    procs.add(proc);
7227                }
7228            }
7229
7230            // Kill the running processes.
7231            for (int i=0; i<procs.size(); i++) {
7232                ProcessRecord pr = procs.get(i);
7233                if (pr == mHomeProcess) {
7234                    // Don't kill the home process along with tasks from the same package.
7235                    continue;
7236                }
7237                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7238                    killUnneededProcessLocked(pr, "remove task");
7239                } else {
7240                    pr.waitingToKill = "remove task";
7241                }
7242            }
7243        }
7244    }
7245
7246    /**
7247     * Removes the task with the specified task id.
7248     *
7249     * @param taskId Identifier of the task to be removed.
7250     * @param flags Additional operational flags.  May be 0 or
7251     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7252     * @return Returns true if the given task was found and removed.
7253     */
7254    private boolean removeTaskByIdLocked(int taskId, int flags) {
7255        TaskRecord tr = recentTaskForIdLocked(taskId);
7256        if (tr != null) {
7257            tr.removeTaskActivitiesLocked(-1, false);
7258            cleanUpRemovedTaskLocked(tr, flags);
7259            return true;
7260        }
7261        return false;
7262    }
7263
7264    @Override
7265    public boolean removeTask(int taskId, int flags) {
7266        synchronized (this) {
7267            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7268                    "removeTask()");
7269            long ident = Binder.clearCallingIdentity();
7270            try {
7271                return removeTaskByIdLocked(taskId, flags);
7272            } finally {
7273                Binder.restoreCallingIdentity(ident);
7274            }
7275        }
7276    }
7277
7278    /**
7279     * TODO: Add mController hook
7280     */
7281    @Override
7282    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7283        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7284                "moveTaskToFront()");
7285
7286        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7287        synchronized(this) {
7288            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7289                    Binder.getCallingUid(), "Task to front")) {
7290                ActivityOptions.abort(options);
7291                return;
7292            }
7293            final long origId = Binder.clearCallingIdentity();
7294            try {
7295                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7296                if (task == null) {
7297                    return;
7298                }
7299                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7300                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7301                    return;
7302                }
7303                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7304            } finally {
7305                Binder.restoreCallingIdentity(origId);
7306            }
7307            ActivityOptions.abort(options);
7308        }
7309    }
7310
7311    @Override
7312    public void moveTaskToBack(int taskId) {
7313        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7314                "moveTaskToBack()");
7315
7316        synchronized(this) {
7317            TaskRecord tr = recentTaskForIdLocked(taskId);
7318            if (tr != null) {
7319                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7320                ActivityStack stack = tr.stack;
7321                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7322                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7323                            Binder.getCallingUid(), "Task to back")) {
7324                        return;
7325                    }
7326                }
7327                final long origId = Binder.clearCallingIdentity();
7328                try {
7329                    stack.moveTaskToBackLocked(taskId, null);
7330                } finally {
7331                    Binder.restoreCallingIdentity(origId);
7332                }
7333            }
7334        }
7335    }
7336
7337    /**
7338     * Moves an activity, and all of the other activities within the same task, to the bottom
7339     * of the history stack.  The activity's order within the task is unchanged.
7340     *
7341     * @param token A reference to the activity we wish to move
7342     * @param nonRoot If false then this only works if the activity is the root
7343     *                of a task; if true it will work for any activity in a task.
7344     * @return Returns true if the move completed, false if not.
7345     */
7346    @Override
7347    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7348        enforceNotIsolatedCaller("moveActivityTaskToBack");
7349        synchronized(this) {
7350            final long origId = Binder.clearCallingIdentity();
7351            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7352            if (taskId >= 0) {
7353                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7354            }
7355            Binder.restoreCallingIdentity(origId);
7356        }
7357        return false;
7358    }
7359
7360    @Override
7361    public void moveTaskBackwards(int task) {
7362        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7363                "moveTaskBackwards()");
7364
7365        synchronized(this) {
7366            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7367                    Binder.getCallingUid(), "Task backwards")) {
7368                return;
7369            }
7370            final long origId = Binder.clearCallingIdentity();
7371            moveTaskBackwardsLocked(task);
7372            Binder.restoreCallingIdentity(origId);
7373        }
7374    }
7375
7376    private final void moveTaskBackwardsLocked(int task) {
7377        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7378    }
7379
7380    @Override
7381    public IBinder getHomeActivityToken() throws RemoteException {
7382        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7383                "getHomeActivityToken()");
7384        synchronized (this) {
7385            return mStackSupervisor.getHomeActivityToken();
7386        }
7387    }
7388
7389    @Override
7390    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7391            IActivityContainerCallback callback) throws RemoteException {
7392        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7393                "createActivityContainer()");
7394        synchronized (this) {
7395            if (parentActivityToken == null) {
7396                throw new IllegalArgumentException("parent token must not be null");
7397            }
7398            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7399            if (r == null) {
7400                return null;
7401            }
7402            if (callback == null) {
7403                throw new IllegalArgumentException("callback must not be null");
7404            }
7405            return mStackSupervisor.createActivityContainer(r, callback);
7406        }
7407    }
7408
7409    @Override
7410    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7411        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7412                "deleteActivityContainer()");
7413        synchronized (this) {
7414            mStackSupervisor.deleteActivityContainer(container);
7415        }
7416    }
7417
7418    @Override
7419    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7420            throws RemoteException {
7421        synchronized (this) {
7422            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7423            if (stack != null) {
7424                return stack.mActivityContainer;
7425            }
7426            return null;
7427        }
7428    }
7429
7430    @Override
7431    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7432        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7433                "moveTaskToStack()");
7434        if (stackId == HOME_STACK_ID) {
7435            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7436                    new RuntimeException("here").fillInStackTrace());
7437        }
7438        synchronized (this) {
7439            long ident = Binder.clearCallingIdentity();
7440            try {
7441                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7442                        + stackId + " toTop=" + toTop);
7443                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7444            } finally {
7445                Binder.restoreCallingIdentity(ident);
7446            }
7447        }
7448    }
7449
7450    @Override
7451    public void resizeStack(int stackBoxId, Rect bounds) {
7452        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7453                "resizeStackBox()");
7454        long ident = Binder.clearCallingIdentity();
7455        try {
7456            mWindowManager.resizeStack(stackBoxId, bounds);
7457        } finally {
7458            Binder.restoreCallingIdentity(ident);
7459        }
7460    }
7461
7462    @Override
7463    public List<StackInfo> getAllStackInfos() {
7464        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7465                "getAllStackInfos()");
7466        long ident = Binder.clearCallingIdentity();
7467        try {
7468            synchronized (this) {
7469                return mStackSupervisor.getAllStackInfosLocked();
7470            }
7471        } finally {
7472            Binder.restoreCallingIdentity(ident);
7473        }
7474    }
7475
7476    @Override
7477    public StackInfo getStackInfo(int stackId) {
7478        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7479                "getStackInfo()");
7480        long ident = Binder.clearCallingIdentity();
7481        try {
7482            synchronized (this) {
7483                return mStackSupervisor.getStackInfoLocked(stackId);
7484            }
7485        } finally {
7486            Binder.restoreCallingIdentity(ident);
7487        }
7488    }
7489
7490    @Override
7491    public boolean isInHomeStack(int taskId) {
7492        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7493                "getStackInfo()");
7494        long ident = Binder.clearCallingIdentity();
7495        try {
7496            synchronized (this) {
7497                TaskRecord tr = recentTaskForIdLocked(taskId);
7498                if (tr != null) {
7499                    return tr.stack.isHomeStack();
7500                }
7501            }
7502        } finally {
7503            Binder.restoreCallingIdentity(ident);
7504        }
7505        return false;
7506    }
7507
7508    @Override
7509    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7510        synchronized(this) {
7511            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7512        }
7513    }
7514
7515    private boolean isLockTaskAuthorized(ComponentName name) {
7516//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7517//                "startLockTaskMode()");
7518//        DevicePolicyManager dpm = (DevicePolicyManager)
7519//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7520//        return dpm != null && dpm.isLockTaskPermitted(name);
7521        return true;
7522    }
7523
7524    private void startLockTaskMode(TaskRecord task) {
7525        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7526            return;
7527        }
7528        long ident = Binder.clearCallingIdentity();
7529        try {
7530            synchronized (this) {
7531                // Since we lost lock on task, make sure it is still there.
7532                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7533                if (task != null) {
7534                    mStackSupervisor.setLockTaskModeLocked(task);
7535                }
7536            }
7537        } finally {
7538            Binder.restoreCallingIdentity(ident);
7539        }
7540    }
7541
7542    @Override
7543    public void startLockTaskMode(int taskId) {
7544        long ident = Binder.clearCallingIdentity();
7545        try {
7546            final TaskRecord task;
7547            synchronized (this) {
7548                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7549            }
7550            if (task != null) {
7551                startLockTaskMode(task);
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(ident);
7555        }
7556    }
7557
7558    @Override
7559    public void startLockTaskMode(IBinder token) {
7560        long ident = Binder.clearCallingIdentity();
7561        try {
7562            final TaskRecord task;
7563            synchronized (this) {
7564                final ActivityRecord r = ActivityRecord.forToken(token);
7565                if (r == null) {
7566                    return;
7567                }
7568                task = r.task;
7569            }
7570            if (task != null) {
7571                startLockTaskMode(task);
7572            }
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public void stopLockTaskMode() {
7580//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7581//                "stopLockTaskMode()");
7582        synchronized (this) {
7583            mStackSupervisor.setLockTaskModeLocked(null);
7584        }
7585    }
7586
7587    @Override
7588    public boolean isInLockTaskMode() {
7589        synchronized (this) {
7590            return mStackSupervisor.isInLockTaskMode();
7591        }
7592    }
7593
7594    // =========================================================
7595    // CONTENT PROVIDERS
7596    // =========================================================
7597
7598    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7599        List<ProviderInfo> providers = null;
7600        try {
7601            providers = AppGlobals.getPackageManager().
7602                queryContentProviders(app.processName, app.uid,
7603                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7604        } catch (RemoteException ex) {
7605        }
7606        if (DEBUG_MU)
7607            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7608        int userId = app.userId;
7609        if (providers != null) {
7610            int N = providers.size();
7611            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7612            for (int i=0; i<N; i++) {
7613                ProviderInfo cpi =
7614                    (ProviderInfo)providers.get(i);
7615                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7616                        cpi.name, cpi.flags);
7617                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7618                    // This is a singleton provider, but a user besides the
7619                    // default user is asking to initialize a process it runs
7620                    // in...  well, no, it doesn't actually run in this process,
7621                    // it runs in the process of the default user.  Get rid of it.
7622                    providers.remove(i);
7623                    N--;
7624                    i--;
7625                    continue;
7626                }
7627
7628                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7629                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7630                if (cpr == null) {
7631                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7632                    mProviderMap.putProviderByClass(comp, cpr);
7633                }
7634                if (DEBUG_MU)
7635                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7636                app.pubProviders.put(cpi.name, cpr);
7637                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7638                    // Don't add this if it is a platform component that is marked
7639                    // to run in multiple processes, because this is actually
7640                    // part of the framework so doesn't make sense to track as a
7641                    // separate apk in the process.
7642                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7643                }
7644                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7645            }
7646        }
7647        return providers;
7648    }
7649
7650    /**
7651     * Check if {@link ProcessRecord} has a possible chance at accessing the
7652     * given {@link ProviderInfo}. Final permission checking is always done
7653     * in {@link ContentProvider}.
7654     */
7655    private final String checkContentProviderPermissionLocked(
7656            ProviderInfo cpi, ProcessRecord r) {
7657        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7658        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7659        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7660                cpi.applicationInfo.uid, cpi.exported)
7661                == PackageManager.PERMISSION_GRANTED) {
7662            return null;
7663        }
7664        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7665                cpi.applicationInfo.uid, cpi.exported)
7666                == PackageManager.PERMISSION_GRANTED) {
7667            return null;
7668        }
7669
7670        PathPermission[] pps = cpi.pathPermissions;
7671        if (pps != null) {
7672            int i = pps.length;
7673            while (i > 0) {
7674                i--;
7675                PathPermission pp = pps[i];
7676                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7677                        cpi.applicationInfo.uid, cpi.exported)
7678                        == PackageManager.PERMISSION_GRANTED) {
7679                    return null;
7680                }
7681                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7682                        cpi.applicationInfo.uid, cpi.exported)
7683                        == PackageManager.PERMISSION_GRANTED) {
7684                    return null;
7685                }
7686            }
7687        }
7688
7689        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7690        if (perms != null) {
7691            for (GrantUri uri : perms.keySet()) {
7692                if (uri.uri.getAuthority().equals(cpi.authority)) {
7693                    return null;
7694                }
7695            }
7696        }
7697
7698        String msg;
7699        if (!cpi.exported) {
7700            msg = "Permission Denial: opening provider " + cpi.name
7701                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7702                    + ", uid=" + callingUid + ") that is not exported from uid "
7703                    + cpi.applicationInfo.uid;
7704        } else {
7705            msg = "Permission Denial: opening provider " + cpi.name
7706                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7707                    + ", uid=" + callingUid + ") requires "
7708                    + cpi.readPermission + " or " + cpi.writePermission;
7709        }
7710        Slog.w(TAG, msg);
7711        return msg;
7712    }
7713
7714    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7715            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7716        if (r != null) {
7717            for (int i=0; i<r.conProviders.size(); i++) {
7718                ContentProviderConnection conn = r.conProviders.get(i);
7719                if (conn.provider == cpr) {
7720                    if (DEBUG_PROVIDER) Slog.v(TAG,
7721                            "Adding provider requested by "
7722                            + r.processName + " from process "
7723                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7724                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7725                    if (stable) {
7726                        conn.stableCount++;
7727                        conn.numStableIncs++;
7728                    } else {
7729                        conn.unstableCount++;
7730                        conn.numUnstableIncs++;
7731                    }
7732                    return conn;
7733                }
7734            }
7735            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7736            if (stable) {
7737                conn.stableCount = 1;
7738                conn.numStableIncs = 1;
7739            } else {
7740                conn.unstableCount = 1;
7741                conn.numUnstableIncs = 1;
7742            }
7743            cpr.connections.add(conn);
7744            r.conProviders.add(conn);
7745            return conn;
7746        }
7747        cpr.addExternalProcessHandleLocked(externalProcessToken);
7748        return null;
7749    }
7750
7751    boolean decProviderCountLocked(ContentProviderConnection conn,
7752            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7753        if (conn != null) {
7754            cpr = conn.provider;
7755            if (DEBUG_PROVIDER) Slog.v(TAG,
7756                    "Removing provider requested by "
7757                    + conn.client.processName + " from process "
7758                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7759                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7760            if (stable) {
7761                conn.stableCount--;
7762            } else {
7763                conn.unstableCount--;
7764            }
7765            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7766                cpr.connections.remove(conn);
7767                conn.client.conProviders.remove(conn);
7768                return true;
7769            }
7770            return false;
7771        }
7772        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7773        return false;
7774    }
7775
7776    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7777            String name, IBinder token, boolean stable, int userId) {
7778        ContentProviderRecord cpr;
7779        ContentProviderConnection conn = null;
7780        ProviderInfo cpi = null;
7781
7782        synchronized(this) {
7783            ProcessRecord r = null;
7784            if (caller != null) {
7785                r = getRecordForAppLocked(caller);
7786                if (r == null) {
7787                    throw new SecurityException(
7788                            "Unable to find app for caller " + caller
7789                          + " (pid=" + Binder.getCallingPid()
7790                          + ") when getting content provider " + name);
7791                }
7792            }
7793
7794            // First check if this content provider has been published...
7795            cpr = mProviderMap.getProviderByName(name, userId);
7796            boolean providerRunning = cpr != null;
7797            if (providerRunning) {
7798                cpi = cpr.info;
7799                String msg;
7800                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7801                    throw new SecurityException(msg);
7802                }
7803
7804                if (r != null && cpr.canRunHere(r)) {
7805                    // This provider has been published or is in the process
7806                    // of being published...  but it is also allowed to run
7807                    // in the caller's process, so don't make a connection
7808                    // and just let the caller instantiate its own instance.
7809                    ContentProviderHolder holder = cpr.newHolder(null);
7810                    // don't give caller the provider object, it needs
7811                    // to make its own.
7812                    holder.provider = null;
7813                    return holder;
7814                }
7815
7816                final long origId = Binder.clearCallingIdentity();
7817
7818                // In this case the provider instance already exists, so we can
7819                // return it right away.
7820                conn = incProviderCountLocked(r, cpr, token, stable);
7821                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7822                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7823                        // If this is a perceptible app accessing the provider,
7824                        // make sure to count it as being accessed and thus
7825                        // back up on the LRU list.  This is good because
7826                        // content providers are often expensive to start.
7827                        updateLruProcessLocked(cpr.proc, false, null);
7828                    }
7829                }
7830
7831                if (cpr.proc != null) {
7832                    if (false) {
7833                        if (cpr.name.flattenToShortString().equals(
7834                                "com.android.providers.calendar/.CalendarProvider2")) {
7835                            Slog.v(TAG, "****************** KILLING "
7836                                + cpr.name.flattenToShortString());
7837                            Process.killProcess(cpr.proc.pid);
7838                        }
7839                    }
7840                    boolean success = updateOomAdjLocked(cpr.proc);
7841                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7842                    // NOTE: there is still a race here where a signal could be
7843                    // pending on the process even though we managed to update its
7844                    // adj level.  Not sure what to do about this, but at least
7845                    // the race is now smaller.
7846                    if (!success) {
7847                        // Uh oh...  it looks like the provider's process
7848                        // has been killed on us.  We need to wait for a new
7849                        // process to be started, and make sure its death
7850                        // doesn't kill our process.
7851                        Slog.i(TAG,
7852                                "Existing provider " + cpr.name.flattenToShortString()
7853                                + " is crashing; detaching " + r);
7854                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7855                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7856                        if (!lastRef) {
7857                            // This wasn't the last ref our process had on
7858                            // the provider...  we have now been killed, bail.
7859                            return null;
7860                        }
7861                        providerRunning = false;
7862                        conn = null;
7863                    }
7864                }
7865
7866                Binder.restoreCallingIdentity(origId);
7867            }
7868
7869            boolean singleton;
7870            if (!providerRunning) {
7871                try {
7872                    cpi = AppGlobals.getPackageManager().
7873                        resolveContentProvider(name,
7874                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7875                } catch (RemoteException ex) {
7876                }
7877                if (cpi == null) {
7878                    return null;
7879                }
7880                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7881                        cpi.name, cpi.flags);
7882                if (singleton) {
7883                    userId = 0;
7884                }
7885                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7886
7887                String msg;
7888                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7889                    throw new SecurityException(msg);
7890                }
7891
7892                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7893                        && !cpi.processName.equals("system")) {
7894                    // If this content provider does not run in the system
7895                    // process, and the system is not yet ready to run other
7896                    // processes, then fail fast instead of hanging.
7897                    throw new IllegalArgumentException(
7898                            "Attempt to launch content provider before system ready");
7899                }
7900
7901                // Make sure that the user who owns this provider is started.  If not,
7902                // we don't want to allow it to run.
7903                if (mStartedUsers.get(userId) == null) {
7904                    Slog.w(TAG, "Unable to launch app "
7905                            + cpi.applicationInfo.packageName + "/"
7906                            + cpi.applicationInfo.uid + " for provider "
7907                            + name + ": user " + userId + " is stopped");
7908                    return null;
7909                }
7910
7911                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7912                cpr = mProviderMap.getProviderByClass(comp, userId);
7913                final boolean firstClass = cpr == null;
7914                if (firstClass) {
7915                    try {
7916                        ApplicationInfo ai =
7917                            AppGlobals.getPackageManager().
7918                                getApplicationInfo(
7919                                        cpi.applicationInfo.packageName,
7920                                        STOCK_PM_FLAGS, userId);
7921                        if (ai == null) {
7922                            Slog.w(TAG, "No package info for content provider "
7923                                    + cpi.name);
7924                            return null;
7925                        }
7926                        ai = getAppInfoForUser(ai, userId);
7927                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7928                    } catch (RemoteException ex) {
7929                        // pm is in same process, this will never happen.
7930                    }
7931                }
7932
7933                if (r != null && cpr.canRunHere(r)) {
7934                    // If this is a multiprocess provider, then just return its
7935                    // info and allow the caller to instantiate it.  Only do
7936                    // this if the provider is the same user as the caller's
7937                    // process, or can run as root (so can be in any process).
7938                    return cpr.newHolder(null);
7939                }
7940
7941                if (DEBUG_PROVIDER) {
7942                    RuntimeException e = new RuntimeException("here");
7943                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7944                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7945                }
7946
7947                // This is single process, and our app is now connecting to it.
7948                // See if we are already in the process of launching this
7949                // provider.
7950                final int N = mLaunchingProviders.size();
7951                int i;
7952                for (i=0; i<N; i++) {
7953                    if (mLaunchingProviders.get(i) == cpr) {
7954                        break;
7955                    }
7956                }
7957
7958                // If the provider is not already being launched, then get it
7959                // started.
7960                if (i >= N) {
7961                    final long origId = Binder.clearCallingIdentity();
7962
7963                    try {
7964                        // Content provider is now in use, its package can't be stopped.
7965                        try {
7966                            AppGlobals.getPackageManager().setPackageStoppedState(
7967                                    cpr.appInfo.packageName, false, userId);
7968                        } catch (RemoteException e) {
7969                        } catch (IllegalArgumentException e) {
7970                            Slog.w(TAG, "Failed trying to unstop package "
7971                                    + cpr.appInfo.packageName + ": " + e);
7972                        }
7973
7974                        // Use existing process if already started
7975                        ProcessRecord proc = getProcessRecordLocked(
7976                                cpi.processName, cpr.appInfo.uid, false);
7977                        if (proc != null && proc.thread != null) {
7978                            if (DEBUG_PROVIDER) {
7979                                Slog.d(TAG, "Installing in existing process " + proc);
7980                            }
7981                            proc.pubProviders.put(cpi.name, cpr);
7982                            try {
7983                                proc.thread.scheduleInstallProvider(cpi);
7984                            } catch (RemoteException e) {
7985                            }
7986                        } else {
7987                            proc = startProcessLocked(cpi.processName,
7988                                    cpr.appInfo, false, 0, "content provider",
7989                                    new ComponentName(cpi.applicationInfo.packageName,
7990                                            cpi.name), false, false, false);
7991                            if (proc == null) {
7992                                Slog.w(TAG, "Unable to launch app "
7993                                        + cpi.applicationInfo.packageName + "/"
7994                                        + cpi.applicationInfo.uid + " for provider "
7995                                        + name + ": process is bad");
7996                                return null;
7997                            }
7998                        }
7999                        cpr.launchingApp = proc;
8000                        mLaunchingProviders.add(cpr);
8001                    } finally {
8002                        Binder.restoreCallingIdentity(origId);
8003                    }
8004                }
8005
8006                // Make sure the provider is published (the same provider class
8007                // may be published under multiple names).
8008                if (firstClass) {
8009                    mProviderMap.putProviderByClass(comp, cpr);
8010                }
8011
8012                mProviderMap.putProviderByName(name, cpr);
8013                conn = incProviderCountLocked(r, cpr, token, stable);
8014                if (conn != null) {
8015                    conn.waiting = true;
8016                }
8017            }
8018        }
8019
8020        // Wait for the provider to be published...
8021        synchronized (cpr) {
8022            while (cpr.provider == null) {
8023                if (cpr.launchingApp == null) {
8024                    Slog.w(TAG, "Unable to launch app "
8025                            + cpi.applicationInfo.packageName + "/"
8026                            + cpi.applicationInfo.uid + " for provider "
8027                            + name + ": launching app became null");
8028                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8029                            UserHandle.getUserId(cpi.applicationInfo.uid),
8030                            cpi.applicationInfo.packageName,
8031                            cpi.applicationInfo.uid, name);
8032                    return null;
8033                }
8034                try {
8035                    if (DEBUG_MU) {
8036                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8037                                + cpr.launchingApp);
8038                    }
8039                    if (conn != null) {
8040                        conn.waiting = true;
8041                    }
8042                    cpr.wait();
8043                } catch (InterruptedException ex) {
8044                } finally {
8045                    if (conn != null) {
8046                        conn.waiting = false;
8047                    }
8048                }
8049            }
8050        }
8051        return cpr != null ? cpr.newHolder(conn) : null;
8052    }
8053
8054    public final ContentProviderHolder getContentProvider(
8055            IApplicationThread caller, String name, int userId, boolean stable) {
8056        enforceNotIsolatedCaller("getContentProvider");
8057        if (caller == null) {
8058            String msg = "null IApplicationThread when getting content provider "
8059                    + name;
8060            Slog.w(TAG, msg);
8061            throw new SecurityException(msg);
8062        }
8063
8064        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8065                false, true, "getContentProvider", null);
8066        return getContentProviderImpl(caller, name, null, stable, userId);
8067    }
8068
8069    public ContentProviderHolder getContentProviderExternal(
8070            String name, int userId, IBinder token) {
8071        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8072            "Do not have permission in call getContentProviderExternal()");
8073        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8074                false, true, "getContentProvider", null);
8075        return getContentProviderExternalUnchecked(name, token, userId);
8076    }
8077
8078    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8079            IBinder token, int userId) {
8080        return getContentProviderImpl(null, name, token, true, userId);
8081    }
8082
8083    /**
8084     * Drop a content provider from a ProcessRecord's bookkeeping
8085     */
8086    public void removeContentProvider(IBinder connection, boolean stable) {
8087        enforceNotIsolatedCaller("removeContentProvider");
8088        long ident = Binder.clearCallingIdentity();
8089        try {
8090            synchronized (this) {
8091                ContentProviderConnection conn;
8092                try {
8093                    conn = (ContentProviderConnection)connection;
8094                } catch (ClassCastException e) {
8095                    String msg ="removeContentProvider: " + connection
8096                            + " not a ContentProviderConnection";
8097                    Slog.w(TAG, msg);
8098                    throw new IllegalArgumentException(msg);
8099                }
8100                if (conn == null) {
8101                    throw new NullPointerException("connection is null");
8102                }
8103                if (decProviderCountLocked(conn, null, null, stable)) {
8104                    updateOomAdjLocked();
8105                }
8106            }
8107        } finally {
8108            Binder.restoreCallingIdentity(ident);
8109        }
8110    }
8111
8112    public void removeContentProviderExternal(String name, IBinder token) {
8113        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8114            "Do not have permission in call removeContentProviderExternal()");
8115        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8116    }
8117
8118    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8119        synchronized (this) {
8120            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8121            if(cpr == null) {
8122                //remove from mProvidersByClass
8123                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8124                return;
8125            }
8126
8127            //update content provider record entry info
8128            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8129            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8130            if (localCpr.hasExternalProcessHandles()) {
8131                if (localCpr.removeExternalProcessHandleLocked(token)) {
8132                    updateOomAdjLocked();
8133                } else {
8134                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8135                            + " with no external reference for token: "
8136                            + token + ".");
8137                }
8138            } else {
8139                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8140                        + " with no external references.");
8141            }
8142        }
8143    }
8144
8145    public final void publishContentProviders(IApplicationThread caller,
8146            List<ContentProviderHolder> providers) {
8147        if (providers == null) {
8148            return;
8149        }
8150
8151        enforceNotIsolatedCaller("publishContentProviders");
8152        synchronized (this) {
8153            final ProcessRecord r = getRecordForAppLocked(caller);
8154            if (DEBUG_MU)
8155                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8156            if (r == null) {
8157                throw new SecurityException(
8158                        "Unable to find app for caller " + caller
8159                      + " (pid=" + Binder.getCallingPid()
8160                      + ") when publishing content providers");
8161            }
8162
8163            final long origId = Binder.clearCallingIdentity();
8164
8165            final int N = providers.size();
8166            for (int i=0; i<N; i++) {
8167                ContentProviderHolder src = providers.get(i);
8168                if (src == null || src.info == null || src.provider == null) {
8169                    continue;
8170                }
8171                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8172                if (DEBUG_MU)
8173                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8174                if (dst != null) {
8175                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8176                    mProviderMap.putProviderByClass(comp, dst);
8177                    String names[] = dst.info.authority.split(";");
8178                    for (int j = 0; j < names.length; j++) {
8179                        mProviderMap.putProviderByName(names[j], dst);
8180                    }
8181
8182                    int NL = mLaunchingProviders.size();
8183                    int j;
8184                    for (j=0; j<NL; j++) {
8185                        if (mLaunchingProviders.get(j) == dst) {
8186                            mLaunchingProviders.remove(j);
8187                            j--;
8188                            NL--;
8189                        }
8190                    }
8191                    synchronized (dst) {
8192                        dst.provider = src.provider;
8193                        dst.proc = r;
8194                        dst.notifyAll();
8195                    }
8196                    updateOomAdjLocked(r);
8197                }
8198            }
8199
8200            Binder.restoreCallingIdentity(origId);
8201        }
8202    }
8203
8204    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8205        ContentProviderConnection conn;
8206        try {
8207            conn = (ContentProviderConnection)connection;
8208        } catch (ClassCastException e) {
8209            String msg ="refContentProvider: " + connection
8210                    + " not a ContentProviderConnection";
8211            Slog.w(TAG, msg);
8212            throw new IllegalArgumentException(msg);
8213        }
8214        if (conn == null) {
8215            throw new NullPointerException("connection is null");
8216        }
8217
8218        synchronized (this) {
8219            if (stable > 0) {
8220                conn.numStableIncs += stable;
8221            }
8222            stable = conn.stableCount + stable;
8223            if (stable < 0) {
8224                throw new IllegalStateException("stableCount < 0: " + stable);
8225            }
8226
8227            if (unstable > 0) {
8228                conn.numUnstableIncs += unstable;
8229            }
8230            unstable = conn.unstableCount + unstable;
8231            if (unstable < 0) {
8232                throw new IllegalStateException("unstableCount < 0: " + unstable);
8233            }
8234
8235            if ((stable+unstable) <= 0) {
8236                throw new IllegalStateException("ref counts can't go to zero here: stable="
8237                        + stable + " unstable=" + unstable);
8238            }
8239            conn.stableCount = stable;
8240            conn.unstableCount = unstable;
8241            return !conn.dead;
8242        }
8243    }
8244
8245    public void unstableProviderDied(IBinder connection) {
8246        ContentProviderConnection conn;
8247        try {
8248            conn = (ContentProviderConnection)connection;
8249        } catch (ClassCastException e) {
8250            String msg ="refContentProvider: " + connection
8251                    + " not a ContentProviderConnection";
8252            Slog.w(TAG, msg);
8253            throw new IllegalArgumentException(msg);
8254        }
8255        if (conn == null) {
8256            throw new NullPointerException("connection is null");
8257        }
8258
8259        // Safely retrieve the content provider associated with the connection.
8260        IContentProvider provider;
8261        synchronized (this) {
8262            provider = conn.provider.provider;
8263        }
8264
8265        if (provider == null) {
8266            // Um, yeah, we're way ahead of you.
8267            return;
8268        }
8269
8270        // Make sure the caller is being honest with us.
8271        if (provider.asBinder().pingBinder()) {
8272            // Er, no, still looks good to us.
8273            synchronized (this) {
8274                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8275                        + " says " + conn + " died, but we don't agree");
8276                return;
8277            }
8278        }
8279
8280        // Well look at that!  It's dead!
8281        synchronized (this) {
8282            if (conn.provider.provider != provider) {
8283                // But something changed...  good enough.
8284                return;
8285            }
8286
8287            ProcessRecord proc = conn.provider.proc;
8288            if (proc == null || proc.thread == null) {
8289                // Seems like the process is already cleaned up.
8290                return;
8291            }
8292
8293            // As far as we're concerned, this is just like receiving a
8294            // death notification...  just a bit prematurely.
8295            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8296                    + ") early provider death");
8297            final long ident = Binder.clearCallingIdentity();
8298            try {
8299                appDiedLocked(proc, proc.pid, proc.thread);
8300            } finally {
8301                Binder.restoreCallingIdentity(ident);
8302            }
8303        }
8304    }
8305
8306    @Override
8307    public void appNotRespondingViaProvider(IBinder connection) {
8308        enforceCallingPermission(
8309                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8310
8311        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8312        if (conn == null) {
8313            Slog.w(TAG, "ContentProviderConnection is null");
8314            return;
8315        }
8316
8317        final ProcessRecord host = conn.provider.proc;
8318        if (host == null) {
8319            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8320            return;
8321        }
8322
8323        final long token = Binder.clearCallingIdentity();
8324        try {
8325            appNotResponding(host, null, null, false, "ContentProvider not responding");
8326        } finally {
8327            Binder.restoreCallingIdentity(token);
8328        }
8329    }
8330
8331    public final void installSystemProviders() {
8332        List<ProviderInfo> providers;
8333        synchronized (this) {
8334            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8335            providers = generateApplicationProvidersLocked(app);
8336            if (providers != null) {
8337                for (int i=providers.size()-1; i>=0; i--) {
8338                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8339                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8340                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8341                                + ": not system .apk");
8342                        providers.remove(i);
8343                    }
8344                }
8345            }
8346        }
8347        if (providers != null) {
8348            mSystemThread.installSystemProviders(providers);
8349        }
8350
8351        mCoreSettingsObserver = new CoreSettingsObserver(this);
8352
8353        mUsageStatsService.monitorPackages();
8354    }
8355
8356    /**
8357     * Allows app to retrieve the MIME type of a URI without having permission
8358     * to access its content provider.
8359     *
8360     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8361     *
8362     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8363     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8364     */
8365    public String getProviderMimeType(Uri uri, int userId) {
8366        enforceNotIsolatedCaller("getProviderMimeType");
8367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8368                userId, false, true, "getProviderMimeType", null);
8369        final String name = uri.getAuthority();
8370        final long ident = Binder.clearCallingIdentity();
8371        ContentProviderHolder holder = null;
8372
8373        try {
8374            holder = getContentProviderExternalUnchecked(name, null, userId);
8375            if (holder != null) {
8376                return holder.provider.getType(uri);
8377            }
8378        } catch (RemoteException e) {
8379            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8380            return null;
8381        } finally {
8382            if (holder != null) {
8383                removeContentProviderExternalUnchecked(name, null, userId);
8384            }
8385            Binder.restoreCallingIdentity(ident);
8386        }
8387
8388        return null;
8389    }
8390
8391    // =========================================================
8392    // GLOBAL MANAGEMENT
8393    // =========================================================
8394
8395    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8396            boolean isolated) {
8397        String proc = customProcess != null ? customProcess : info.processName;
8398        BatteryStatsImpl.Uid.Proc ps = null;
8399        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8400        int uid = info.uid;
8401        if (isolated) {
8402            int userId = UserHandle.getUserId(uid);
8403            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8404            while (true) {
8405                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8406                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8407                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8408                }
8409                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8410                mNextIsolatedProcessUid++;
8411                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8412                    // No process for this uid, use it.
8413                    break;
8414                }
8415                stepsLeft--;
8416                if (stepsLeft <= 0) {
8417                    return null;
8418                }
8419            }
8420        }
8421        return new ProcessRecord(stats, info, proc, uid);
8422    }
8423
8424    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8425        ProcessRecord app;
8426        if (!isolated) {
8427            app = getProcessRecordLocked(info.processName, info.uid, true);
8428        } else {
8429            app = null;
8430        }
8431
8432        if (app == null) {
8433            app = newProcessRecordLocked(info, null, isolated);
8434            mProcessNames.put(info.processName, app.uid, app);
8435            if (isolated) {
8436                mIsolatedProcesses.put(app.uid, app);
8437            }
8438            updateLruProcessLocked(app, false, null);
8439            updateOomAdjLocked();
8440        }
8441
8442        // This package really, really can not be stopped.
8443        try {
8444            AppGlobals.getPackageManager().setPackageStoppedState(
8445                    info.packageName, false, UserHandle.getUserId(app.uid));
8446        } catch (RemoteException e) {
8447        } catch (IllegalArgumentException e) {
8448            Slog.w(TAG, "Failed trying to unstop package "
8449                    + info.packageName + ": " + e);
8450        }
8451
8452        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8453                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8454            app.persistent = true;
8455            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8456        }
8457        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8458            mPersistentStartingProcesses.add(app);
8459            startProcessLocked(app, "added application", app.processName);
8460        }
8461
8462        return app;
8463    }
8464
8465    public void unhandledBack() {
8466        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8467                "unhandledBack()");
8468
8469        synchronized(this) {
8470            final long origId = Binder.clearCallingIdentity();
8471            try {
8472                getFocusedStack().unhandledBackLocked();
8473            } finally {
8474                Binder.restoreCallingIdentity(origId);
8475            }
8476        }
8477    }
8478
8479    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8480        enforceNotIsolatedCaller("openContentUri");
8481        final int userId = UserHandle.getCallingUserId();
8482        String name = uri.getAuthority();
8483        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8484        ParcelFileDescriptor pfd = null;
8485        if (cph != null) {
8486            // We record the binder invoker's uid in thread-local storage before
8487            // going to the content provider to open the file.  Later, in the code
8488            // that handles all permissions checks, we look for this uid and use
8489            // that rather than the Activity Manager's own uid.  The effect is that
8490            // we do the check against the caller's permissions even though it looks
8491            // to the content provider like the Activity Manager itself is making
8492            // the request.
8493            sCallerIdentity.set(new Identity(
8494                    Binder.getCallingPid(), Binder.getCallingUid()));
8495            try {
8496                pfd = cph.provider.openFile(null, uri, "r", null);
8497            } catch (FileNotFoundException e) {
8498                // do nothing; pfd will be returned null
8499            } finally {
8500                // Ensure that whatever happens, we clean up the identity state
8501                sCallerIdentity.remove();
8502            }
8503
8504            // We've got the fd now, so we're done with the provider.
8505            removeContentProviderExternalUnchecked(name, null, userId);
8506        } else {
8507            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8508        }
8509        return pfd;
8510    }
8511
8512    // Actually is sleeping or shutting down or whatever else in the future
8513    // is an inactive state.
8514    public boolean isSleepingOrShuttingDown() {
8515        return mSleeping || mShuttingDown;
8516    }
8517
8518    public boolean isSleeping() {
8519        return mSleeping;
8520    }
8521
8522    void goingToSleep() {
8523        synchronized(this) {
8524            mWentToSleep = true;
8525            updateEventDispatchingLocked();
8526            goToSleepIfNeededLocked();
8527        }
8528    }
8529
8530    void finishRunningVoiceLocked() {
8531        if (mRunningVoice) {
8532            mRunningVoice = false;
8533            goToSleepIfNeededLocked();
8534        }
8535    }
8536
8537    void goToSleepIfNeededLocked() {
8538        if (mWentToSleep && !mRunningVoice) {
8539            if (!mSleeping) {
8540                mSleeping = true;
8541                mStackSupervisor.goingToSleepLocked();
8542
8543                // Initialize the wake times of all processes.
8544                checkExcessivePowerUsageLocked(false);
8545                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8546                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8547                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8548            }
8549        }
8550    }
8551
8552    @Override
8553    public boolean shutdown(int timeout) {
8554        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8555                != PackageManager.PERMISSION_GRANTED) {
8556            throw new SecurityException("Requires permission "
8557                    + android.Manifest.permission.SHUTDOWN);
8558        }
8559
8560        boolean timedout = false;
8561
8562        synchronized(this) {
8563            mShuttingDown = true;
8564            updateEventDispatchingLocked();
8565            timedout = mStackSupervisor.shutdownLocked(timeout);
8566        }
8567
8568        mAppOpsService.shutdown();
8569        mUsageStatsService.shutdown();
8570        mBatteryStatsService.shutdown();
8571        synchronized (this) {
8572            mProcessStats.shutdownLocked();
8573        }
8574
8575        return timedout;
8576    }
8577
8578    public final void activitySlept(IBinder token) {
8579        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8580
8581        final long origId = Binder.clearCallingIdentity();
8582
8583        synchronized (this) {
8584            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8585            if (r != null) {
8586                mStackSupervisor.activitySleptLocked(r);
8587            }
8588        }
8589
8590        Binder.restoreCallingIdentity(origId);
8591    }
8592
8593    void logLockScreen(String msg) {
8594        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8595                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8596                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8597                mStackSupervisor.mDismissKeyguardOnNextActivity);
8598    }
8599
8600    private void comeOutOfSleepIfNeededLocked() {
8601        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8602            if (mSleeping) {
8603                mSleeping = false;
8604                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8605            }
8606        }
8607    }
8608
8609    void wakingUp() {
8610        synchronized(this) {
8611            mWentToSleep = false;
8612            updateEventDispatchingLocked();
8613            comeOutOfSleepIfNeededLocked();
8614        }
8615    }
8616
8617    void startRunningVoiceLocked() {
8618        if (!mRunningVoice) {
8619            mRunningVoice = true;
8620            comeOutOfSleepIfNeededLocked();
8621        }
8622    }
8623
8624    private void updateEventDispatchingLocked() {
8625        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8626    }
8627
8628    public void setLockScreenShown(boolean shown) {
8629        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8630                != PackageManager.PERMISSION_GRANTED) {
8631            throw new SecurityException("Requires permission "
8632                    + android.Manifest.permission.DEVICE_POWER);
8633        }
8634
8635        synchronized(this) {
8636            long ident = Binder.clearCallingIdentity();
8637            try {
8638                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8639                mLockScreenShown = shown;
8640                comeOutOfSleepIfNeededLocked();
8641            } finally {
8642                Binder.restoreCallingIdentity(ident);
8643            }
8644        }
8645    }
8646
8647    public void stopAppSwitches() {
8648        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8649                != PackageManager.PERMISSION_GRANTED) {
8650            throw new SecurityException("Requires permission "
8651                    + android.Manifest.permission.STOP_APP_SWITCHES);
8652        }
8653
8654        synchronized(this) {
8655            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8656                    + APP_SWITCH_DELAY_TIME;
8657            mDidAppSwitch = false;
8658            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8659            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8660            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8661        }
8662    }
8663
8664    public void resumeAppSwitches() {
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            // Note that we don't execute any pending app switches... we will
8673            // let those wait until either the timeout, or the next start
8674            // activity request.
8675            mAppSwitchesAllowedTime = 0;
8676        }
8677    }
8678
8679    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8680            String name) {
8681        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8682            return true;
8683        }
8684
8685        final int perm = checkComponentPermission(
8686                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8687                callingUid, -1, true);
8688        if (perm == PackageManager.PERMISSION_GRANTED) {
8689            return true;
8690        }
8691
8692        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8693        return false;
8694    }
8695
8696    public void setDebugApp(String packageName, boolean waitForDebugger,
8697            boolean persistent) {
8698        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8699                "setDebugApp()");
8700
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            // Note that this is not really thread safe if there are multiple
8704            // callers into it at the same time, but that's not a situation we
8705            // care about.
8706            if (persistent) {
8707                final ContentResolver resolver = mContext.getContentResolver();
8708                Settings.Global.putString(
8709                    resolver, Settings.Global.DEBUG_APP,
8710                    packageName);
8711                Settings.Global.putInt(
8712                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8713                    waitForDebugger ? 1 : 0);
8714            }
8715
8716            synchronized (this) {
8717                if (!persistent) {
8718                    mOrigDebugApp = mDebugApp;
8719                    mOrigWaitForDebugger = mWaitForDebugger;
8720                }
8721                mDebugApp = packageName;
8722                mWaitForDebugger = waitForDebugger;
8723                mDebugTransient = !persistent;
8724                if (packageName != null) {
8725                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8726                            false, UserHandle.USER_ALL, "set debug app");
8727                }
8728            }
8729        } finally {
8730            Binder.restoreCallingIdentity(ident);
8731        }
8732    }
8733
8734    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8735        synchronized (this) {
8736            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8737            if (!isDebuggable) {
8738                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8739                    throw new SecurityException("Process not debuggable: " + app.packageName);
8740                }
8741            }
8742
8743            mOpenGlTraceApp = processName;
8744        }
8745    }
8746
8747    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8748            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8749        synchronized (this) {
8750            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8751            if (!isDebuggable) {
8752                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8753                    throw new SecurityException("Process not debuggable: " + app.packageName);
8754                }
8755            }
8756            mProfileApp = processName;
8757            mProfileFile = profileFile;
8758            if (mProfileFd != null) {
8759                try {
8760                    mProfileFd.close();
8761                } catch (IOException e) {
8762                }
8763                mProfileFd = null;
8764            }
8765            mProfileFd = profileFd;
8766            mProfileType = 0;
8767            mAutoStopProfiler = autoStopProfiler;
8768        }
8769    }
8770
8771    @Override
8772    public void setAlwaysFinish(boolean enabled) {
8773        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8774                "setAlwaysFinish()");
8775
8776        Settings.Global.putInt(
8777                mContext.getContentResolver(),
8778                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8779
8780        synchronized (this) {
8781            mAlwaysFinishActivities = enabled;
8782        }
8783    }
8784
8785    @Override
8786    public void setActivityController(IActivityController controller) {
8787        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8788                "setActivityController()");
8789        synchronized (this) {
8790            mController = controller;
8791            Watchdog.getInstance().setActivityController(controller);
8792        }
8793    }
8794
8795    @Override
8796    public void setUserIsMonkey(boolean userIsMonkey) {
8797        synchronized (this) {
8798            synchronized (mPidsSelfLocked) {
8799                final int callingPid = Binder.getCallingPid();
8800                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8801                if (precessRecord == null) {
8802                    throw new SecurityException("Unknown process: " + callingPid);
8803                }
8804                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8805                    throw new SecurityException("Only an instrumentation process "
8806                            + "with a UiAutomation can call setUserIsMonkey");
8807                }
8808            }
8809            mUserIsMonkey = userIsMonkey;
8810        }
8811    }
8812
8813    @Override
8814    public boolean isUserAMonkey() {
8815        synchronized (this) {
8816            // If there is a controller also implies the user is a monkey.
8817            return (mUserIsMonkey || mController != null);
8818        }
8819    }
8820
8821    public void requestBugReport() {
8822        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8823        SystemProperties.set("ctl.start", "bugreport");
8824    }
8825
8826    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8827        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8828    }
8829
8830    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8831        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8832            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8833        }
8834        return KEY_DISPATCHING_TIMEOUT;
8835    }
8836
8837    @Override
8838    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8839        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8840                != PackageManager.PERMISSION_GRANTED) {
8841            throw new SecurityException("Requires permission "
8842                    + android.Manifest.permission.FILTER_EVENTS);
8843        }
8844        ProcessRecord proc;
8845        long timeout;
8846        synchronized (this) {
8847            synchronized (mPidsSelfLocked) {
8848                proc = mPidsSelfLocked.get(pid);
8849            }
8850            timeout = getInputDispatchingTimeoutLocked(proc);
8851        }
8852
8853        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8854            return -1;
8855        }
8856
8857        return timeout;
8858    }
8859
8860    /**
8861     * Handle input dispatching timeouts.
8862     * Returns whether input dispatching should be aborted or not.
8863     */
8864    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8865            final ActivityRecord activity, final ActivityRecord parent,
8866            final boolean aboveSystem, String reason) {
8867        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8868                != PackageManager.PERMISSION_GRANTED) {
8869            throw new SecurityException("Requires permission "
8870                    + android.Manifest.permission.FILTER_EVENTS);
8871        }
8872
8873        final String annotation;
8874        if (reason == null) {
8875            annotation = "Input dispatching timed out";
8876        } else {
8877            annotation = "Input dispatching timed out (" + reason + ")";
8878        }
8879
8880        if (proc != null) {
8881            synchronized (this) {
8882                if (proc.debugging) {
8883                    return false;
8884                }
8885
8886                if (mDidDexOpt) {
8887                    // Give more time since we were dexopting.
8888                    mDidDexOpt = false;
8889                    return false;
8890                }
8891
8892                if (proc.instrumentationClass != null) {
8893                    Bundle info = new Bundle();
8894                    info.putString("shortMsg", "keyDispatchingTimedOut");
8895                    info.putString("longMsg", annotation);
8896                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8897                    return true;
8898                }
8899            }
8900            mHandler.post(new Runnable() {
8901                @Override
8902                public void run() {
8903                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8904                }
8905            });
8906        }
8907
8908        return true;
8909    }
8910
8911    public Bundle getAssistContextExtras(int requestType) {
8912        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8913                "getAssistContextExtras()");
8914        PendingAssistExtras pae;
8915        Bundle extras = new Bundle();
8916        synchronized (this) {
8917            ActivityRecord activity = getFocusedStack().mResumedActivity;
8918            if (activity == null) {
8919                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8920                return null;
8921            }
8922            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8923            if (activity.app == null || activity.app.thread == null) {
8924                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8925                return extras;
8926            }
8927            if (activity.app.pid == Binder.getCallingPid()) {
8928                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8929                return extras;
8930            }
8931            pae = new PendingAssistExtras(activity);
8932            try {
8933                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8934                        requestType);
8935                mPendingAssistExtras.add(pae);
8936                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8937            } catch (RemoteException e) {
8938                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8939                return extras;
8940            }
8941        }
8942        synchronized (pae) {
8943            while (!pae.haveResult) {
8944                try {
8945                    pae.wait();
8946                } catch (InterruptedException e) {
8947                }
8948            }
8949            if (pae.result != null) {
8950                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8951            }
8952        }
8953        synchronized (this) {
8954            mPendingAssistExtras.remove(pae);
8955            mHandler.removeCallbacks(pae);
8956        }
8957        return extras;
8958    }
8959
8960    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8961        PendingAssistExtras pae = (PendingAssistExtras)token;
8962        synchronized (pae) {
8963            pae.result = extras;
8964            pae.haveResult = true;
8965            pae.notifyAll();
8966        }
8967    }
8968
8969    public void registerProcessObserver(IProcessObserver observer) {
8970        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8971                "registerProcessObserver()");
8972        synchronized (this) {
8973            mProcessObservers.register(observer);
8974        }
8975    }
8976
8977    @Override
8978    public void unregisterProcessObserver(IProcessObserver observer) {
8979        synchronized (this) {
8980            mProcessObservers.unregister(observer);
8981        }
8982    }
8983
8984    @Override
8985    public boolean convertFromTranslucent(IBinder token) {
8986        final long origId = Binder.clearCallingIdentity();
8987        try {
8988            synchronized (this) {
8989                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8990                if (r == null) {
8991                    return false;
8992                }
8993                if (r.changeWindowTranslucency(true)) {
8994                    mWindowManager.setAppFullscreen(token, true);
8995                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8996                    return true;
8997                }
8998                return false;
8999            }
9000        } finally {
9001            Binder.restoreCallingIdentity(origId);
9002        }
9003    }
9004
9005    @Override
9006    public boolean convertToTranslucent(IBinder token) {
9007        final long origId = Binder.clearCallingIdentity();
9008        try {
9009            synchronized (this) {
9010                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9011                if (r == null) {
9012                    return false;
9013                }
9014                if (r.changeWindowTranslucency(false)) {
9015                    r.task.stack.convertToTranslucent(r);
9016                    mWindowManager.setAppFullscreen(token, false);
9017                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9018                    return true;
9019                }
9020                return false;
9021            }
9022        } finally {
9023            Binder.restoreCallingIdentity(origId);
9024        }
9025    }
9026
9027    @Override
9028    public void setImmersive(IBinder token, boolean immersive) {
9029        synchronized(this) {
9030            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9031            if (r == null) {
9032                throw new IllegalArgumentException();
9033            }
9034            r.immersive = immersive;
9035
9036            // update associated state if we're frontmost
9037            if (r == mFocusedActivity) {
9038                if (DEBUG_IMMERSIVE) {
9039                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9040                }
9041                applyUpdateLockStateLocked(r);
9042            }
9043        }
9044    }
9045
9046    @Override
9047    public boolean isImmersive(IBinder token) {
9048        synchronized (this) {
9049            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9050            if (r == null) {
9051                throw new IllegalArgumentException();
9052            }
9053            return r.immersive;
9054        }
9055    }
9056
9057    public boolean isTopActivityImmersive() {
9058        enforceNotIsolatedCaller("startActivity");
9059        synchronized (this) {
9060            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9061            return (r != null) ? r.immersive : false;
9062        }
9063    }
9064
9065    public final void enterSafeMode() {
9066        synchronized(this) {
9067            // It only makes sense to do this before the system is ready
9068            // and started launching other packages.
9069            if (!mSystemReady) {
9070                try {
9071                    AppGlobals.getPackageManager().enterSafeMode();
9072                } catch (RemoteException e) {
9073                }
9074            }
9075
9076            mSafeMode = true;
9077        }
9078    }
9079
9080    public final void showSafeModeOverlay() {
9081        View v = LayoutInflater.from(mContext).inflate(
9082                com.android.internal.R.layout.safe_mode, null);
9083        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9084        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9085        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9086        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9087        lp.gravity = Gravity.BOTTOM | Gravity.START;
9088        lp.format = v.getBackground().getOpacity();
9089        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9090                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9091        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9092        ((WindowManager)mContext.getSystemService(
9093                Context.WINDOW_SERVICE)).addView(v, lp);
9094    }
9095
9096    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9097        if (!(sender instanceof PendingIntentRecord)) {
9098            return;
9099        }
9100        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9101        synchronized (stats) {
9102            if (mBatteryStatsService.isOnBattery()) {
9103                mBatteryStatsService.enforceCallingPermission();
9104                PendingIntentRecord rec = (PendingIntentRecord)sender;
9105                int MY_UID = Binder.getCallingUid();
9106                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9107                BatteryStatsImpl.Uid.Pkg pkg =
9108                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9109                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9110                pkg.incWakeupsLocked();
9111            }
9112        }
9113    }
9114
9115    public boolean killPids(int[] pids, String pReason, boolean secure) {
9116        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9117            throw new SecurityException("killPids only available to the system");
9118        }
9119        String reason = (pReason == null) ? "Unknown" : pReason;
9120        // XXX Note: don't acquire main activity lock here, because the window
9121        // manager calls in with its locks held.
9122
9123        boolean killed = false;
9124        synchronized (mPidsSelfLocked) {
9125            int[] types = new int[pids.length];
9126            int worstType = 0;
9127            for (int i=0; i<pids.length; i++) {
9128                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9129                if (proc != null) {
9130                    int type = proc.setAdj;
9131                    types[i] = type;
9132                    if (type > worstType) {
9133                        worstType = type;
9134                    }
9135                }
9136            }
9137
9138            // If the worst oom_adj is somewhere in the cached proc LRU range,
9139            // then constrain it so we will kill all cached procs.
9140            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9141                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9142                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9143            }
9144
9145            // If this is not a secure call, don't let it kill processes that
9146            // are important.
9147            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9148                worstType = ProcessList.SERVICE_ADJ;
9149            }
9150
9151            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9152            for (int i=0; i<pids.length; i++) {
9153                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9154                if (proc == null) {
9155                    continue;
9156                }
9157                int adj = proc.setAdj;
9158                if (adj >= worstType && !proc.killedByAm) {
9159                    killUnneededProcessLocked(proc, reason);
9160                    killed = true;
9161                }
9162            }
9163        }
9164        return killed;
9165    }
9166
9167    @Override
9168    public void killUid(int uid, String reason) {
9169        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9170            throw new SecurityException("killUid only available to the system");
9171        }
9172        synchronized (this) {
9173            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9174                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9175                    reason != null ? reason : "kill uid");
9176        }
9177    }
9178
9179    @Override
9180    public boolean killProcessesBelowForeground(String reason) {
9181        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9182            throw new SecurityException("killProcessesBelowForeground() only available to system");
9183        }
9184
9185        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9186    }
9187
9188    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9189        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9190            throw new SecurityException("killProcessesBelowAdj() only available to system");
9191        }
9192
9193        boolean killed = false;
9194        synchronized (mPidsSelfLocked) {
9195            final int size = mPidsSelfLocked.size();
9196            for (int i = 0; i < size; i++) {
9197                final int pid = mPidsSelfLocked.keyAt(i);
9198                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9199                if (proc == null) continue;
9200
9201                final int adj = proc.setAdj;
9202                if (adj > belowAdj && !proc.killedByAm) {
9203                    killUnneededProcessLocked(proc, reason);
9204                    killed = true;
9205                }
9206            }
9207        }
9208        return killed;
9209    }
9210
9211    @Override
9212    public void hang(final IBinder who, boolean allowRestart) {
9213        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9214                != PackageManager.PERMISSION_GRANTED) {
9215            throw new SecurityException("Requires permission "
9216                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9217        }
9218
9219        final IBinder.DeathRecipient death = new DeathRecipient() {
9220            @Override
9221            public void binderDied() {
9222                synchronized (this) {
9223                    notifyAll();
9224                }
9225            }
9226        };
9227
9228        try {
9229            who.linkToDeath(death, 0);
9230        } catch (RemoteException e) {
9231            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9232            return;
9233        }
9234
9235        synchronized (this) {
9236            Watchdog.getInstance().setAllowRestart(allowRestart);
9237            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9238            synchronized (death) {
9239                while (who.isBinderAlive()) {
9240                    try {
9241                        death.wait();
9242                    } catch (InterruptedException e) {
9243                    }
9244                }
9245            }
9246            Watchdog.getInstance().setAllowRestart(true);
9247        }
9248    }
9249
9250    @Override
9251    public void restart() {
9252        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9253                != PackageManager.PERMISSION_GRANTED) {
9254            throw new SecurityException("Requires permission "
9255                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9256        }
9257
9258        Log.i(TAG, "Sending shutdown broadcast...");
9259
9260        BroadcastReceiver br = new BroadcastReceiver() {
9261            @Override public void onReceive(Context context, Intent intent) {
9262                // Now the broadcast is done, finish up the low-level shutdown.
9263                Log.i(TAG, "Shutting down activity manager...");
9264                shutdown(10000);
9265                Log.i(TAG, "Shutdown complete, restarting!");
9266                Process.killProcess(Process.myPid());
9267                System.exit(10);
9268            }
9269        };
9270
9271        // First send the high-level shut down broadcast.
9272        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9273        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9274        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9275        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9276        mContext.sendOrderedBroadcastAsUser(intent,
9277                UserHandle.ALL, null, br, mHandler, 0, null, null);
9278        */
9279        br.onReceive(mContext, intent);
9280    }
9281
9282    private long getLowRamTimeSinceIdle(long now) {
9283        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9284    }
9285
9286    @Override
9287    public void performIdleMaintenance() {
9288        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9289                != PackageManager.PERMISSION_GRANTED) {
9290            throw new SecurityException("Requires permission "
9291                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9292        }
9293
9294        synchronized (this) {
9295            final long now = SystemClock.uptimeMillis();
9296            final long timeSinceLastIdle = now - mLastIdleTime;
9297            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9298            mLastIdleTime = now;
9299            mLowRamTimeSinceLastIdle = 0;
9300            if (mLowRamStartTime != 0) {
9301                mLowRamStartTime = now;
9302            }
9303
9304            StringBuilder sb = new StringBuilder(128);
9305            sb.append("Idle maintenance over ");
9306            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9307            sb.append(" low RAM for ");
9308            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9309            Slog.i(TAG, sb.toString());
9310
9311            // If at least 1/3 of our time since the last idle period has been spent
9312            // with RAM low, then we want to kill processes.
9313            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9314
9315            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9316                ProcessRecord proc = mLruProcesses.get(i);
9317                if (proc.notCachedSinceIdle) {
9318                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9319                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9320                        if (doKilling && proc.initialIdlePss != 0
9321                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9322                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9323                                    + " from " + proc.initialIdlePss + ")");
9324                        }
9325                    }
9326                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9327                    proc.notCachedSinceIdle = true;
9328                    proc.initialIdlePss = 0;
9329                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9330                            isSleeping(), now);
9331                }
9332            }
9333
9334            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9335            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9336        }
9337    }
9338
9339    private void retrieveSettings() {
9340        final ContentResolver resolver = mContext.getContentResolver();
9341        String debugApp = Settings.Global.getString(
9342            resolver, Settings.Global.DEBUG_APP);
9343        boolean waitForDebugger = Settings.Global.getInt(
9344            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9345        boolean alwaysFinishActivities = Settings.Global.getInt(
9346            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9347        boolean forceRtl = Settings.Global.getInt(
9348                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9349        // Transfer any global setting for forcing RTL layout, into a System Property
9350        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9351
9352        Configuration configuration = new Configuration();
9353        Settings.System.getConfiguration(resolver, configuration);
9354        if (forceRtl) {
9355            // This will take care of setting the correct layout direction flags
9356            configuration.setLayoutDirection(configuration.locale);
9357        }
9358
9359        synchronized (this) {
9360            mDebugApp = mOrigDebugApp = debugApp;
9361            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9362            mAlwaysFinishActivities = alwaysFinishActivities;
9363            // This happens before any activities are started, so we can
9364            // change mConfiguration in-place.
9365            updateConfigurationLocked(configuration, null, false, true);
9366            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9367        }
9368    }
9369
9370    public boolean testIsSystemReady() {
9371        // no need to synchronize(this) just to read & return the value
9372        return mSystemReady;
9373    }
9374
9375    private static File getCalledPreBootReceiversFile() {
9376        File dataDir = Environment.getDataDirectory();
9377        File systemDir = new File(dataDir, "system");
9378        File fname = new File(systemDir, "called_pre_boots.dat");
9379        return fname;
9380    }
9381
9382    static final int LAST_DONE_VERSION = 10000;
9383
9384    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9385        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9386        File file = getCalledPreBootReceiversFile();
9387        FileInputStream fis = null;
9388        try {
9389            fis = new FileInputStream(file);
9390            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9391            int fvers = dis.readInt();
9392            if (fvers == LAST_DONE_VERSION) {
9393                String vers = dis.readUTF();
9394                String codename = dis.readUTF();
9395                String build = dis.readUTF();
9396                if (android.os.Build.VERSION.RELEASE.equals(vers)
9397                        && android.os.Build.VERSION.CODENAME.equals(codename)
9398                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9399                    int num = dis.readInt();
9400                    while (num > 0) {
9401                        num--;
9402                        String pkg = dis.readUTF();
9403                        String cls = dis.readUTF();
9404                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9405                    }
9406                }
9407            }
9408        } catch (FileNotFoundException e) {
9409        } catch (IOException e) {
9410            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9411        } finally {
9412            if (fis != null) {
9413                try {
9414                    fis.close();
9415                } catch (IOException e) {
9416                }
9417            }
9418        }
9419        return lastDoneReceivers;
9420    }
9421
9422    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9423        File file = getCalledPreBootReceiversFile();
9424        FileOutputStream fos = null;
9425        DataOutputStream dos = null;
9426        try {
9427            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9428            fos = new FileOutputStream(file);
9429            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9430            dos.writeInt(LAST_DONE_VERSION);
9431            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9432            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9433            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9434            dos.writeInt(list.size());
9435            for (int i=0; i<list.size(); i++) {
9436                dos.writeUTF(list.get(i).getPackageName());
9437                dos.writeUTF(list.get(i).getClassName());
9438            }
9439        } catch (IOException e) {
9440            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9441            file.delete();
9442        } finally {
9443            FileUtils.sync(fos);
9444            if (dos != null) {
9445                try {
9446                    dos.close();
9447                } catch (IOException e) {
9448                    // TODO Auto-generated catch block
9449                    e.printStackTrace();
9450                }
9451            }
9452        }
9453    }
9454
9455    public void systemReady(final Runnable goingCallback) {
9456        synchronized(this) {
9457            if (mSystemReady) {
9458                if (goingCallback != null) goingCallback.run();
9459                return;
9460            }
9461
9462            // Check to see if there are any update receivers to run.
9463            if (!mDidUpdate) {
9464                if (mWaitingUpdate) {
9465                    return;
9466                }
9467                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9468                List<ResolveInfo> ris = null;
9469                try {
9470                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9471                            intent, null, 0, 0);
9472                } catch (RemoteException e) {
9473                }
9474                if (ris != null) {
9475                    for (int i=ris.size()-1; i>=0; i--) {
9476                        if ((ris.get(i).activityInfo.applicationInfo.flags
9477                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9478                            ris.remove(i);
9479                        }
9480                    }
9481                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9482
9483                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9484
9485                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9486                    for (int i=0; i<ris.size(); i++) {
9487                        ActivityInfo ai = ris.get(i).activityInfo;
9488                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9489                        if (lastDoneReceivers.contains(comp)) {
9490                            // We already did the pre boot receiver for this app with the current
9491                            // platform version, so don't do it again...
9492                            ris.remove(i);
9493                            i--;
9494                            // ...however, do keep it as one that has been done, so we don't
9495                            // forget about it when rewriting the file of last done receivers.
9496                            doneReceivers.add(comp);
9497                        }
9498                    }
9499
9500                    final int[] users = getUsersLocked();
9501                    for (int i=0; i<ris.size(); i++) {
9502                        ActivityInfo ai = ris.get(i).activityInfo;
9503                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9504                        doneReceivers.add(comp);
9505                        intent.setComponent(comp);
9506                        for (int j=0; j<users.length; j++) {
9507                            IIntentReceiver finisher = null;
9508                            if (i == ris.size()-1 && j == users.length-1) {
9509                                finisher = new IIntentReceiver.Stub() {
9510                                    public void performReceive(Intent intent, int resultCode,
9511                                            String data, Bundle extras, boolean ordered,
9512                                            boolean sticky, int sendingUser) {
9513                                        // The raw IIntentReceiver interface is called
9514                                        // with the AM lock held, so redispatch to
9515                                        // execute our code without the lock.
9516                                        mHandler.post(new Runnable() {
9517                                            public void run() {
9518                                                synchronized (ActivityManagerService.this) {
9519                                                    mDidUpdate = true;
9520                                                }
9521                                                writeLastDonePreBootReceivers(doneReceivers);
9522                                                showBootMessage(mContext.getText(
9523                                                        R.string.android_upgrading_complete),
9524                                                        false);
9525                                                systemReady(goingCallback);
9526                                            }
9527                                        });
9528                                    }
9529                                };
9530                            }
9531                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9532                                    + " for user " + users[j]);
9533                            broadcastIntentLocked(null, null, intent, null, finisher,
9534                                    0, null, null, null, AppOpsManager.OP_NONE,
9535                                    true, false, MY_PID, Process.SYSTEM_UID,
9536                                    users[j]);
9537                            if (finisher != null) {
9538                                mWaitingUpdate = true;
9539                            }
9540                        }
9541                    }
9542                }
9543                if (mWaitingUpdate) {
9544                    return;
9545                }
9546                mDidUpdate = true;
9547            }
9548
9549            mAppOpsService.systemReady();
9550            mSystemReady = true;
9551        }
9552
9553        ArrayList<ProcessRecord> procsToKill = null;
9554        synchronized(mPidsSelfLocked) {
9555            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9556                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9557                if (!isAllowedWhileBooting(proc.info)){
9558                    if (procsToKill == null) {
9559                        procsToKill = new ArrayList<ProcessRecord>();
9560                    }
9561                    procsToKill.add(proc);
9562                }
9563            }
9564        }
9565
9566        synchronized(this) {
9567            if (procsToKill != null) {
9568                for (int i=procsToKill.size()-1; i>=0; i--) {
9569                    ProcessRecord proc = procsToKill.get(i);
9570                    Slog.i(TAG, "Removing system update proc: " + proc);
9571                    removeProcessLocked(proc, true, false, "system update done");
9572                }
9573            }
9574
9575            // Now that we have cleaned up any update processes, we
9576            // are ready to start launching real processes and know that
9577            // we won't trample on them any more.
9578            mProcessesReady = true;
9579        }
9580
9581        Slog.i(TAG, "System now ready");
9582        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9583            SystemClock.uptimeMillis());
9584
9585        synchronized(this) {
9586            // Make sure we have no pre-ready processes sitting around.
9587
9588            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9589                ResolveInfo ri = mContext.getPackageManager()
9590                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9591                                STOCK_PM_FLAGS);
9592                CharSequence errorMsg = null;
9593                if (ri != null) {
9594                    ActivityInfo ai = ri.activityInfo;
9595                    ApplicationInfo app = ai.applicationInfo;
9596                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9597                        mTopAction = Intent.ACTION_FACTORY_TEST;
9598                        mTopData = null;
9599                        mTopComponent = new ComponentName(app.packageName,
9600                                ai.name);
9601                    } else {
9602                        errorMsg = mContext.getResources().getText(
9603                                com.android.internal.R.string.factorytest_not_system);
9604                    }
9605                } else {
9606                    errorMsg = mContext.getResources().getText(
9607                            com.android.internal.R.string.factorytest_no_action);
9608                }
9609                if (errorMsg != null) {
9610                    mTopAction = null;
9611                    mTopData = null;
9612                    mTopComponent = null;
9613                    Message msg = Message.obtain();
9614                    msg.what = SHOW_FACTORY_ERROR_MSG;
9615                    msg.getData().putCharSequence("msg", errorMsg);
9616                    mHandler.sendMessage(msg);
9617                }
9618            }
9619        }
9620
9621        retrieveSettings();
9622
9623        synchronized (this) {
9624            readGrantedUriPermissionsLocked();
9625        }
9626
9627        if (goingCallback != null) goingCallback.run();
9628
9629        mSystemServiceManager.startUser(mCurrentUserId);
9630
9631        synchronized (this) {
9632            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9633                try {
9634                    List apps = AppGlobals.getPackageManager().
9635                        getPersistentApplications(STOCK_PM_FLAGS);
9636                    if (apps != null) {
9637                        int N = apps.size();
9638                        int i;
9639                        for (i=0; i<N; i++) {
9640                            ApplicationInfo info
9641                                = (ApplicationInfo)apps.get(i);
9642                            if (info != null &&
9643                                    !info.packageName.equals("android")) {
9644                                addAppLocked(info, false);
9645                            }
9646                        }
9647                    }
9648                } catch (RemoteException ex) {
9649                    // pm is in same process, this will never happen.
9650                }
9651            }
9652
9653            // Start up initial activity.
9654            mBooting = true;
9655
9656            try {
9657                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9658                    Message msg = Message.obtain();
9659                    msg.what = SHOW_UID_ERROR_MSG;
9660                    mHandler.sendMessage(msg);
9661                }
9662            } catch (RemoteException e) {
9663            }
9664
9665            long ident = Binder.clearCallingIdentity();
9666            try {
9667                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9668                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9669                        | Intent.FLAG_RECEIVER_FOREGROUND);
9670                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9671                broadcastIntentLocked(null, null, intent,
9672                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9673                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9674                intent = new Intent(Intent.ACTION_USER_STARTING);
9675                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9676                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9677                broadcastIntentLocked(null, null, intent,
9678                        null, new IIntentReceiver.Stub() {
9679                            @Override
9680                            public void performReceive(Intent intent, int resultCode, String data,
9681                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9682                                    throws RemoteException {
9683                            }
9684                        }, 0, null, null,
9685                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9686                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9687            } catch (Throwable t) {
9688                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9689            } finally {
9690                Binder.restoreCallingIdentity(ident);
9691            }
9692            mStackSupervisor.resumeTopActivitiesLocked();
9693            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9694        }
9695    }
9696
9697    private boolean makeAppCrashingLocked(ProcessRecord app,
9698            String shortMsg, String longMsg, String stackTrace) {
9699        app.crashing = true;
9700        app.crashingReport = generateProcessError(app,
9701                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9702        startAppProblemLocked(app);
9703        app.stopFreezingAllLocked();
9704        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9705    }
9706
9707    private void makeAppNotRespondingLocked(ProcessRecord app,
9708            String activity, String shortMsg, String longMsg) {
9709        app.notResponding = true;
9710        app.notRespondingReport = generateProcessError(app,
9711                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9712                activity, shortMsg, longMsg, null);
9713        startAppProblemLocked(app);
9714        app.stopFreezingAllLocked();
9715    }
9716
9717    /**
9718     * Generate a process error record, suitable for attachment to a ProcessRecord.
9719     *
9720     * @param app The ProcessRecord in which the error occurred.
9721     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9722     *                      ActivityManager.AppErrorStateInfo
9723     * @param activity The activity associated with the crash, if known.
9724     * @param shortMsg Short message describing the crash.
9725     * @param longMsg Long message describing the crash.
9726     * @param stackTrace Full crash stack trace, may be null.
9727     *
9728     * @return Returns a fully-formed AppErrorStateInfo record.
9729     */
9730    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9731            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9732        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9733
9734        report.condition = condition;
9735        report.processName = app.processName;
9736        report.pid = app.pid;
9737        report.uid = app.info.uid;
9738        report.tag = activity;
9739        report.shortMsg = shortMsg;
9740        report.longMsg = longMsg;
9741        report.stackTrace = stackTrace;
9742
9743        return report;
9744    }
9745
9746    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9747        synchronized (this) {
9748            app.crashing = false;
9749            app.crashingReport = null;
9750            app.notResponding = false;
9751            app.notRespondingReport = null;
9752            if (app.anrDialog == fromDialog) {
9753                app.anrDialog = null;
9754            }
9755            if (app.waitDialog == fromDialog) {
9756                app.waitDialog = null;
9757            }
9758            if (app.pid > 0 && app.pid != MY_PID) {
9759                handleAppCrashLocked(app, null, null, null);
9760                killUnneededProcessLocked(app, "user request after error");
9761            }
9762        }
9763    }
9764
9765    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9766            String stackTrace) {
9767        long now = SystemClock.uptimeMillis();
9768
9769        Long crashTime;
9770        if (!app.isolated) {
9771            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9772        } else {
9773            crashTime = null;
9774        }
9775        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9776            // This process loses!
9777            Slog.w(TAG, "Process " + app.info.processName
9778                    + " has crashed too many times: killing!");
9779            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9780                    app.userId, app.info.processName, app.uid);
9781            mStackSupervisor.handleAppCrashLocked(app);
9782            if (!app.persistent) {
9783                // We don't want to start this process again until the user
9784                // explicitly does so...  but for persistent process, we really
9785                // need to keep it running.  If a persistent process is actually
9786                // repeatedly crashing, then badness for everyone.
9787                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9788                        app.info.processName);
9789                if (!app.isolated) {
9790                    // XXX We don't have a way to mark isolated processes
9791                    // as bad, since they don't have a peristent identity.
9792                    mBadProcesses.put(app.info.processName, app.uid,
9793                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9794                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9795                }
9796                app.bad = true;
9797                app.removed = true;
9798                // Don't let services in this process be restarted and potentially
9799                // annoy the user repeatedly.  Unless it is persistent, since those
9800                // processes run critical code.
9801                removeProcessLocked(app, false, false, "crash");
9802                mStackSupervisor.resumeTopActivitiesLocked();
9803                return false;
9804            }
9805            mStackSupervisor.resumeTopActivitiesLocked();
9806        } else {
9807            mStackSupervisor.finishTopRunningActivityLocked(app);
9808        }
9809
9810        // Bump up the crash count of any services currently running in the proc.
9811        for (int i=app.services.size()-1; i>=0; i--) {
9812            // Any services running in the application need to be placed
9813            // back in the pending list.
9814            ServiceRecord sr = app.services.valueAt(i);
9815            sr.crashCount++;
9816        }
9817
9818        // If the crashing process is what we consider to be the "home process" and it has been
9819        // replaced by a third-party app, clear the package preferred activities from packages
9820        // with a home activity running in the process to prevent a repeatedly crashing app
9821        // from blocking the user to manually clear the list.
9822        final ArrayList<ActivityRecord> activities = app.activities;
9823        if (app == mHomeProcess && activities.size() > 0
9824                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9825            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9826                final ActivityRecord r = activities.get(activityNdx);
9827                if (r.isHomeActivity()) {
9828                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9829                    try {
9830                        ActivityThread.getPackageManager()
9831                                .clearPackagePreferredActivities(r.packageName);
9832                    } catch (RemoteException c) {
9833                        // pm is in same process, this will never happen.
9834                    }
9835                }
9836            }
9837        }
9838
9839        if (!app.isolated) {
9840            // XXX Can't keep track of crash times for isolated processes,
9841            // because they don't have a perisistent identity.
9842            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9843        }
9844
9845        return true;
9846    }
9847
9848    void startAppProblemLocked(ProcessRecord app) {
9849        if (app.userId == mCurrentUserId) {
9850            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9851                    mContext, app.info.packageName, app.info.flags);
9852        } else {
9853            // If this app is not running under the current user, then we
9854            // can't give it a report button because that would require
9855            // launching the report UI under a different user.
9856            app.errorReportReceiver = null;
9857        }
9858        skipCurrentReceiverLocked(app);
9859    }
9860
9861    void skipCurrentReceiverLocked(ProcessRecord app) {
9862        for (BroadcastQueue queue : mBroadcastQueues) {
9863            queue.skipCurrentReceiverLocked(app);
9864        }
9865    }
9866
9867    /**
9868     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9869     * The application process will exit immediately after this call returns.
9870     * @param app object of the crashing app, null for the system server
9871     * @param crashInfo describing the exception
9872     */
9873    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9874        ProcessRecord r = findAppProcess(app, "Crash");
9875        final String processName = app == null ? "system_server"
9876                : (r == null ? "unknown" : r.processName);
9877
9878        handleApplicationCrashInner("crash", r, processName, crashInfo);
9879    }
9880
9881    /* Native crash reporting uses this inner version because it needs to be somewhat
9882     * decoupled from the AM-managed cleanup lifecycle
9883     */
9884    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9885            ApplicationErrorReport.CrashInfo crashInfo) {
9886        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9887                UserHandle.getUserId(Binder.getCallingUid()), processName,
9888                r == null ? -1 : r.info.flags,
9889                crashInfo.exceptionClassName,
9890                crashInfo.exceptionMessage,
9891                crashInfo.throwFileName,
9892                crashInfo.throwLineNumber);
9893
9894        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9895
9896        crashApplication(r, crashInfo);
9897    }
9898
9899    public void handleApplicationStrictModeViolation(
9900            IBinder app,
9901            int violationMask,
9902            StrictMode.ViolationInfo info) {
9903        ProcessRecord r = findAppProcess(app, "StrictMode");
9904        if (r == null) {
9905            return;
9906        }
9907
9908        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9909            Integer stackFingerprint = info.hashCode();
9910            boolean logIt = true;
9911            synchronized (mAlreadyLoggedViolatedStacks) {
9912                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9913                    logIt = false;
9914                    // TODO: sub-sample into EventLog for these, with
9915                    // the info.durationMillis?  Then we'd get
9916                    // the relative pain numbers, without logging all
9917                    // the stack traces repeatedly.  We'd want to do
9918                    // likewise in the client code, which also does
9919                    // dup suppression, before the Binder call.
9920                } else {
9921                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9922                        mAlreadyLoggedViolatedStacks.clear();
9923                    }
9924                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9925                }
9926            }
9927            if (logIt) {
9928                logStrictModeViolationToDropBox(r, info);
9929            }
9930        }
9931
9932        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9933            AppErrorResult result = new AppErrorResult();
9934            synchronized (this) {
9935                final long origId = Binder.clearCallingIdentity();
9936
9937                Message msg = Message.obtain();
9938                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9939                HashMap<String, Object> data = new HashMap<String, Object>();
9940                data.put("result", result);
9941                data.put("app", r);
9942                data.put("violationMask", violationMask);
9943                data.put("info", info);
9944                msg.obj = data;
9945                mHandler.sendMessage(msg);
9946
9947                Binder.restoreCallingIdentity(origId);
9948            }
9949            int res = result.get();
9950            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9951        }
9952    }
9953
9954    // Depending on the policy in effect, there could be a bunch of
9955    // these in quick succession so we try to batch these together to
9956    // minimize disk writes, number of dropbox entries, and maximize
9957    // compression, by having more fewer, larger records.
9958    private void logStrictModeViolationToDropBox(
9959            ProcessRecord process,
9960            StrictMode.ViolationInfo info) {
9961        if (info == null) {
9962            return;
9963        }
9964        final boolean isSystemApp = process == null ||
9965                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9966                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9967        final String processName = process == null ? "unknown" : process.processName;
9968        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9969        final DropBoxManager dbox = (DropBoxManager)
9970                mContext.getSystemService(Context.DROPBOX_SERVICE);
9971
9972        // Exit early if the dropbox isn't configured to accept this report type.
9973        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9974
9975        boolean bufferWasEmpty;
9976        boolean needsFlush;
9977        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9978        synchronized (sb) {
9979            bufferWasEmpty = sb.length() == 0;
9980            appendDropBoxProcessHeaders(process, processName, sb);
9981            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9982            sb.append("System-App: ").append(isSystemApp).append("\n");
9983            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9984            if (info.violationNumThisLoop != 0) {
9985                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9986            }
9987            if (info.numAnimationsRunning != 0) {
9988                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9989            }
9990            if (info.broadcastIntentAction != null) {
9991                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9992            }
9993            if (info.durationMillis != -1) {
9994                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9995            }
9996            if (info.numInstances != -1) {
9997                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9998            }
9999            if (info.tags != null) {
10000                for (String tag : info.tags) {
10001                    sb.append("Span-Tag: ").append(tag).append("\n");
10002                }
10003            }
10004            sb.append("\n");
10005            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10006                sb.append(info.crashInfo.stackTrace);
10007            }
10008            sb.append("\n");
10009
10010            // Only buffer up to ~64k.  Various logging bits truncate
10011            // things at 128k.
10012            needsFlush = (sb.length() > 64 * 1024);
10013        }
10014
10015        // Flush immediately if the buffer's grown too large, or this
10016        // is a non-system app.  Non-system apps are isolated with a
10017        // different tag & policy and not batched.
10018        //
10019        // Batching is useful during internal testing with
10020        // StrictMode settings turned up high.  Without batching,
10021        // thousands of separate files could be created on boot.
10022        if (!isSystemApp || needsFlush) {
10023            new Thread("Error dump: " + dropboxTag) {
10024                @Override
10025                public void run() {
10026                    String report;
10027                    synchronized (sb) {
10028                        report = sb.toString();
10029                        sb.delete(0, sb.length());
10030                        sb.trimToSize();
10031                    }
10032                    if (report.length() != 0) {
10033                        dbox.addText(dropboxTag, report);
10034                    }
10035                }
10036            }.start();
10037            return;
10038        }
10039
10040        // System app batching:
10041        if (!bufferWasEmpty) {
10042            // An existing dropbox-writing thread is outstanding, so
10043            // we don't need to start it up.  The existing thread will
10044            // catch the buffer appends we just did.
10045            return;
10046        }
10047
10048        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10049        // (After this point, we shouldn't access AMS internal data structures.)
10050        new Thread("Error dump: " + dropboxTag) {
10051            @Override
10052            public void run() {
10053                // 5 second sleep to let stacks arrive and be batched together
10054                try {
10055                    Thread.sleep(5000);  // 5 seconds
10056                } catch (InterruptedException e) {}
10057
10058                String errorReport;
10059                synchronized (mStrictModeBuffer) {
10060                    errorReport = mStrictModeBuffer.toString();
10061                    if (errorReport.length() == 0) {
10062                        return;
10063                    }
10064                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10065                    mStrictModeBuffer.trimToSize();
10066                }
10067                dbox.addText(dropboxTag, errorReport);
10068            }
10069        }.start();
10070    }
10071
10072    /**
10073     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10074     * @param app object of the crashing app, null for the system server
10075     * @param tag reported by the caller
10076     * @param crashInfo describing the context of the error
10077     * @return true if the process should exit immediately (WTF is fatal)
10078     */
10079    public boolean handleApplicationWtf(IBinder app, String tag,
10080            ApplicationErrorReport.CrashInfo crashInfo) {
10081        ProcessRecord r = findAppProcess(app, "WTF");
10082        final String processName = app == null ? "system_server"
10083                : (r == null ? "unknown" : r.processName);
10084
10085        EventLog.writeEvent(EventLogTags.AM_WTF,
10086                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10087                processName,
10088                r == null ? -1 : r.info.flags,
10089                tag, crashInfo.exceptionMessage);
10090
10091        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10092
10093        if (r != null && r.pid != Process.myPid() &&
10094                Settings.Global.getInt(mContext.getContentResolver(),
10095                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10096            crashApplication(r, crashInfo);
10097            return true;
10098        } else {
10099            return false;
10100        }
10101    }
10102
10103    /**
10104     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10105     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10106     */
10107    private ProcessRecord findAppProcess(IBinder app, String reason) {
10108        if (app == null) {
10109            return null;
10110        }
10111
10112        synchronized (this) {
10113            final int NP = mProcessNames.getMap().size();
10114            for (int ip=0; ip<NP; ip++) {
10115                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10116                final int NA = apps.size();
10117                for (int ia=0; ia<NA; ia++) {
10118                    ProcessRecord p = apps.valueAt(ia);
10119                    if (p.thread != null && p.thread.asBinder() == app) {
10120                        return p;
10121                    }
10122                }
10123            }
10124
10125            Slog.w(TAG, "Can't find mystery application for " + reason
10126                    + " from pid=" + Binder.getCallingPid()
10127                    + " uid=" + Binder.getCallingUid() + ": " + app);
10128            return null;
10129        }
10130    }
10131
10132    /**
10133     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10134     * to append various headers to the dropbox log text.
10135     */
10136    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10137            StringBuilder sb) {
10138        // Watchdog thread ends up invoking this function (with
10139        // a null ProcessRecord) to add the stack file to dropbox.
10140        // Do not acquire a lock on this (am) in such cases, as it
10141        // could cause a potential deadlock, if and when watchdog
10142        // is invoked due to unavailability of lock on am and it
10143        // would prevent watchdog from killing system_server.
10144        if (process == null) {
10145            sb.append("Process: ").append(processName).append("\n");
10146            return;
10147        }
10148        // Note: ProcessRecord 'process' is guarded by the service
10149        // instance.  (notably process.pkgList, which could otherwise change
10150        // concurrently during execution of this method)
10151        synchronized (this) {
10152            sb.append("Process: ").append(processName).append("\n");
10153            int flags = process.info.flags;
10154            IPackageManager pm = AppGlobals.getPackageManager();
10155            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10156            for (int ip=0; ip<process.pkgList.size(); ip++) {
10157                String pkg = process.pkgList.keyAt(ip);
10158                sb.append("Package: ").append(pkg);
10159                try {
10160                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10161                    if (pi != null) {
10162                        sb.append(" v").append(pi.versionCode);
10163                        if (pi.versionName != null) {
10164                            sb.append(" (").append(pi.versionName).append(")");
10165                        }
10166                    }
10167                } catch (RemoteException e) {
10168                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10169                }
10170                sb.append("\n");
10171            }
10172        }
10173    }
10174
10175    private static String processClass(ProcessRecord process) {
10176        if (process == null || process.pid == MY_PID) {
10177            return "system_server";
10178        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10179            return "system_app";
10180        } else {
10181            return "data_app";
10182        }
10183    }
10184
10185    /**
10186     * Write a description of an error (crash, WTF, ANR) to the drop box.
10187     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10188     * @param process which caused the error, null means the system server
10189     * @param activity which triggered the error, null if unknown
10190     * @param parent activity related to the error, null if unknown
10191     * @param subject line related to the error, null if absent
10192     * @param report in long form describing the error, null if absent
10193     * @param logFile to include in the report, null if none
10194     * @param crashInfo giving an application stack trace, null if absent
10195     */
10196    public void addErrorToDropBox(String eventType,
10197            ProcessRecord process, String processName, ActivityRecord activity,
10198            ActivityRecord parent, String subject,
10199            final String report, final File logFile,
10200            final ApplicationErrorReport.CrashInfo crashInfo) {
10201        // NOTE -- this must never acquire the ActivityManagerService lock,
10202        // otherwise the watchdog may be prevented from resetting the system.
10203
10204        final String dropboxTag = processClass(process) + "_" + eventType;
10205        final DropBoxManager dbox = (DropBoxManager)
10206                mContext.getSystemService(Context.DROPBOX_SERVICE);
10207
10208        // Exit early if the dropbox isn't configured to accept this report type.
10209        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10210
10211        final StringBuilder sb = new StringBuilder(1024);
10212        appendDropBoxProcessHeaders(process, processName, sb);
10213        if (activity != null) {
10214            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10215        }
10216        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10217            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10218        }
10219        if (parent != null && parent != activity) {
10220            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10221        }
10222        if (subject != null) {
10223            sb.append("Subject: ").append(subject).append("\n");
10224        }
10225        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10226        if (Debug.isDebuggerConnected()) {
10227            sb.append("Debugger: Connected\n");
10228        }
10229        sb.append("\n");
10230
10231        // Do the rest in a worker thread to avoid blocking the caller on I/O
10232        // (After this point, we shouldn't access AMS internal data structures.)
10233        Thread worker = new Thread("Error dump: " + dropboxTag) {
10234            @Override
10235            public void run() {
10236                if (report != null) {
10237                    sb.append(report);
10238                }
10239                if (logFile != null) {
10240                    try {
10241                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10242                                    "\n\n[[TRUNCATED]]"));
10243                    } catch (IOException e) {
10244                        Slog.e(TAG, "Error reading " + logFile, e);
10245                    }
10246                }
10247                if (crashInfo != null && crashInfo.stackTrace != null) {
10248                    sb.append(crashInfo.stackTrace);
10249                }
10250
10251                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10252                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10253                if (lines > 0) {
10254                    sb.append("\n");
10255
10256                    // Merge several logcat streams, and take the last N lines
10257                    InputStreamReader input = null;
10258                    try {
10259                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10260                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10261                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10262
10263                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10264                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10265                        input = new InputStreamReader(logcat.getInputStream());
10266
10267                        int num;
10268                        char[] buf = new char[8192];
10269                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10270                    } catch (IOException e) {
10271                        Slog.e(TAG, "Error running logcat", e);
10272                    } finally {
10273                        if (input != null) try { input.close(); } catch (IOException e) {}
10274                    }
10275                }
10276
10277                dbox.addText(dropboxTag, sb.toString());
10278            }
10279        };
10280
10281        if (process == null) {
10282            // If process is null, we are being called from some internal code
10283            // and may be about to die -- run this synchronously.
10284            worker.run();
10285        } else {
10286            worker.start();
10287        }
10288    }
10289
10290    /**
10291     * Bring up the "unexpected error" dialog box for a crashing app.
10292     * Deal with edge cases (intercepts from instrumented applications,
10293     * ActivityController, error intent receivers, that sort of thing).
10294     * @param r the application crashing
10295     * @param crashInfo describing the failure
10296     */
10297    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10298        long timeMillis = System.currentTimeMillis();
10299        String shortMsg = crashInfo.exceptionClassName;
10300        String longMsg = crashInfo.exceptionMessage;
10301        String stackTrace = crashInfo.stackTrace;
10302        if (shortMsg != null && longMsg != null) {
10303            longMsg = shortMsg + ": " + longMsg;
10304        } else if (shortMsg != null) {
10305            longMsg = shortMsg;
10306        }
10307
10308        AppErrorResult result = new AppErrorResult();
10309        synchronized (this) {
10310            if (mController != null) {
10311                try {
10312                    String name = r != null ? r.processName : null;
10313                    int pid = r != null ? r.pid : Binder.getCallingPid();
10314                    if (!mController.appCrashed(name, pid,
10315                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10316                        Slog.w(TAG, "Force-killing crashed app " + name
10317                                + " at watcher's request");
10318                        Process.killProcess(pid);
10319                        return;
10320                    }
10321                } catch (RemoteException e) {
10322                    mController = null;
10323                    Watchdog.getInstance().setActivityController(null);
10324                }
10325            }
10326
10327            final long origId = Binder.clearCallingIdentity();
10328
10329            // If this process is running instrumentation, finish it.
10330            if (r != null && r.instrumentationClass != null) {
10331                Slog.w(TAG, "Error in app " + r.processName
10332                      + " running instrumentation " + r.instrumentationClass + ":");
10333                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10334                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10335                Bundle info = new Bundle();
10336                info.putString("shortMsg", shortMsg);
10337                info.putString("longMsg", longMsg);
10338                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10339                Binder.restoreCallingIdentity(origId);
10340                return;
10341            }
10342
10343            // If we can't identify the process or it's already exceeded its crash quota,
10344            // quit right away without showing a crash dialog.
10345            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10346                Binder.restoreCallingIdentity(origId);
10347                return;
10348            }
10349
10350            Message msg = Message.obtain();
10351            msg.what = SHOW_ERROR_MSG;
10352            HashMap data = new HashMap();
10353            data.put("result", result);
10354            data.put("app", r);
10355            msg.obj = data;
10356            mHandler.sendMessage(msg);
10357
10358            Binder.restoreCallingIdentity(origId);
10359        }
10360
10361        int res = result.get();
10362
10363        Intent appErrorIntent = null;
10364        synchronized (this) {
10365            if (r != null && !r.isolated) {
10366                // XXX Can't keep track of crash time for isolated processes,
10367                // since they don't have a persistent identity.
10368                mProcessCrashTimes.put(r.info.processName, r.uid,
10369                        SystemClock.uptimeMillis());
10370            }
10371            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10372                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10373            }
10374        }
10375
10376        if (appErrorIntent != null) {
10377            try {
10378                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10379            } catch (ActivityNotFoundException e) {
10380                Slog.w(TAG, "bug report receiver dissappeared", e);
10381            }
10382        }
10383    }
10384
10385    Intent createAppErrorIntentLocked(ProcessRecord r,
10386            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10387        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10388        if (report == null) {
10389            return null;
10390        }
10391        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10392        result.setComponent(r.errorReportReceiver);
10393        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10394        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10395        return result;
10396    }
10397
10398    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10399            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10400        if (r.errorReportReceiver == null) {
10401            return null;
10402        }
10403
10404        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10405            return null;
10406        }
10407
10408        ApplicationErrorReport report = new ApplicationErrorReport();
10409        report.packageName = r.info.packageName;
10410        report.installerPackageName = r.errorReportReceiver.getPackageName();
10411        report.processName = r.processName;
10412        report.time = timeMillis;
10413        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10414
10415        if (r.crashing || r.forceCrashReport) {
10416            report.type = ApplicationErrorReport.TYPE_CRASH;
10417            report.crashInfo = crashInfo;
10418        } else if (r.notResponding) {
10419            report.type = ApplicationErrorReport.TYPE_ANR;
10420            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10421
10422            report.anrInfo.activity = r.notRespondingReport.tag;
10423            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10424            report.anrInfo.info = r.notRespondingReport.longMsg;
10425        }
10426
10427        return report;
10428    }
10429
10430    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10431        enforceNotIsolatedCaller("getProcessesInErrorState");
10432        // assume our apps are happy - lazy create the list
10433        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10434
10435        final boolean allUsers = ActivityManager.checkUidPermission(
10436                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10437                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10438        int userId = UserHandle.getUserId(Binder.getCallingUid());
10439
10440        synchronized (this) {
10441
10442            // iterate across all processes
10443            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10444                ProcessRecord app = mLruProcesses.get(i);
10445                if (!allUsers && app.userId != userId) {
10446                    continue;
10447                }
10448                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10449                    // This one's in trouble, so we'll generate a report for it
10450                    // crashes are higher priority (in case there's a crash *and* an anr)
10451                    ActivityManager.ProcessErrorStateInfo report = null;
10452                    if (app.crashing) {
10453                        report = app.crashingReport;
10454                    } else if (app.notResponding) {
10455                        report = app.notRespondingReport;
10456                    }
10457
10458                    if (report != null) {
10459                        if (errList == null) {
10460                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10461                        }
10462                        errList.add(report);
10463                    } else {
10464                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10465                                " crashing = " + app.crashing +
10466                                " notResponding = " + app.notResponding);
10467                    }
10468                }
10469            }
10470        }
10471
10472        return errList;
10473    }
10474
10475    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10476        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10477            if (currApp != null) {
10478                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10479            }
10480            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10481        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10482            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10483        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10484            if (currApp != null) {
10485                currApp.lru = 0;
10486            }
10487            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10488        } else if (adj >= ProcessList.SERVICE_ADJ) {
10489            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10490        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10491            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10492        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10493            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10494        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10495            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10496        } else {
10497            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10498        }
10499    }
10500
10501    private void fillInProcMemInfo(ProcessRecord app,
10502            ActivityManager.RunningAppProcessInfo outInfo) {
10503        outInfo.pid = app.pid;
10504        outInfo.uid = app.info.uid;
10505        if (mHeavyWeightProcess == app) {
10506            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10507        }
10508        if (app.persistent) {
10509            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10510        }
10511        if (app.activities.size() > 0) {
10512            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10513        }
10514        outInfo.lastTrimLevel = app.trimMemoryLevel;
10515        int adj = app.curAdj;
10516        outInfo.importance = oomAdjToImportance(adj, outInfo);
10517        outInfo.importanceReasonCode = app.adjTypeCode;
10518        outInfo.processState = app.curProcState;
10519    }
10520
10521    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10522        enforceNotIsolatedCaller("getRunningAppProcesses");
10523        // Lazy instantiation of list
10524        List<ActivityManager.RunningAppProcessInfo> runList = null;
10525        final boolean allUsers = ActivityManager.checkUidPermission(
10526                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10527                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10528        int userId = UserHandle.getUserId(Binder.getCallingUid());
10529        synchronized (this) {
10530            // Iterate across all processes
10531            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10532                ProcessRecord app = mLruProcesses.get(i);
10533                if (!allUsers && app.userId != userId) {
10534                    continue;
10535                }
10536                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10537                    // Generate process state info for running application
10538                    ActivityManager.RunningAppProcessInfo currApp =
10539                        new ActivityManager.RunningAppProcessInfo(app.processName,
10540                                app.pid, app.getPackageList());
10541                    fillInProcMemInfo(app, currApp);
10542                    if (app.adjSource instanceof ProcessRecord) {
10543                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10544                        currApp.importanceReasonImportance = oomAdjToImportance(
10545                                app.adjSourceOom, null);
10546                    } else if (app.adjSource instanceof ActivityRecord) {
10547                        ActivityRecord r = (ActivityRecord)app.adjSource;
10548                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10549                    }
10550                    if (app.adjTarget instanceof ComponentName) {
10551                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10552                    }
10553                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10554                    //        + " lru=" + currApp.lru);
10555                    if (runList == null) {
10556                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10557                    }
10558                    runList.add(currApp);
10559                }
10560            }
10561        }
10562        return runList;
10563    }
10564
10565    public List<ApplicationInfo> getRunningExternalApplications() {
10566        enforceNotIsolatedCaller("getRunningExternalApplications");
10567        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10568        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10569        if (runningApps != null && runningApps.size() > 0) {
10570            Set<String> extList = new HashSet<String>();
10571            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10572                if (app.pkgList != null) {
10573                    for (String pkg : app.pkgList) {
10574                        extList.add(pkg);
10575                    }
10576                }
10577            }
10578            IPackageManager pm = AppGlobals.getPackageManager();
10579            for (String pkg : extList) {
10580                try {
10581                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10582                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10583                        retList.add(info);
10584                    }
10585                } catch (RemoteException e) {
10586                }
10587            }
10588        }
10589        return retList;
10590    }
10591
10592    @Override
10593    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10594        enforceNotIsolatedCaller("getMyMemoryState");
10595        synchronized (this) {
10596            ProcessRecord proc;
10597            synchronized (mPidsSelfLocked) {
10598                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10599            }
10600            fillInProcMemInfo(proc, outInfo);
10601        }
10602    }
10603
10604    @Override
10605    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10606        if (checkCallingPermission(android.Manifest.permission.DUMP)
10607                != PackageManager.PERMISSION_GRANTED) {
10608            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10609                    + Binder.getCallingPid()
10610                    + ", uid=" + Binder.getCallingUid()
10611                    + " without permission "
10612                    + android.Manifest.permission.DUMP);
10613            return;
10614        }
10615
10616        boolean dumpAll = false;
10617        boolean dumpClient = false;
10618        String dumpPackage = null;
10619
10620        int opti = 0;
10621        while (opti < args.length) {
10622            String opt = args[opti];
10623            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10624                break;
10625            }
10626            opti++;
10627            if ("-a".equals(opt)) {
10628                dumpAll = true;
10629            } else if ("-c".equals(opt)) {
10630                dumpClient = true;
10631            } else if ("-h".equals(opt)) {
10632                pw.println("Activity manager dump options:");
10633                pw.println("  [-a] [-c] [-h] [cmd] ...");
10634                pw.println("  cmd may be one of:");
10635                pw.println("    a[ctivities]: activity stack state");
10636                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10637                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10638                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10639                pw.println("    o[om]: out of memory management");
10640                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10641                pw.println("    provider [COMP_SPEC]: provider client-side state");
10642                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10643                pw.println("    service [COMP_SPEC]: service client-side state");
10644                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10645                pw.println("    all: dump all activities");
10646                pw.println("    top: dump the top activity");
10647                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10648                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10649                pw.println("    a partial substring in a component name, a");
10650                pw.println("    hex object identifier.");
10651                pw.println("  -a: include all available server state.");
10652                pw.println("  -c: include client state.");
10653                return;
10654            } else {
10655                pw.println("Unknown argument: " + opt + "; use -h for help");
10656            }
10657        }
10658
10659        long origId = Binder.clearCallingIdentity();
10660        boolean more = false;
10661        // Is the caller requesting to dump a particular piece of data?
10662        if (opti < args.length) {
10663            String cmd = args[opti];
10664            opti++;
10665            if ("activities".equals(cmd) || "a".equals(cmd)) {
10666                synchronized (this) {
10667                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10668                }
10669            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10670                String[] newArgs;
10671                String name;
10672                if (opti >= args.length) {
10673                    name = null;
10674                    newArgs = EMPTY_STRING_ARRAY;
10675                } else {
10676                    name = args[opti];
10677                    opti++;
10678                    newArgs = new String[args.length - opti];
10679                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10680                            args.length - opti);
10681                }
10682                synchronized (this) {
10683                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10684                }
10685            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10686                String[] newArgs;
10687                String name;
10688                if (opti >= args.length) {
10689                    name = null;
10690                    newArgs = EMPTY_STRING_ARRAY;
10691                } else {
10692                    name = args[opti];
10693                    opti++;
10694                    newArgs = new String[args.length - opti];
10695                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10696                            args.length - opti);
10697                }
10698                synchronized (this) {
10699                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10700                }
10701            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10702                String[] newArgs;
10703                String name;
10704                if (opti >= args.length) {
10705                    name = null;
10706                    newArgs = EMPTY_STRING_ARRAY;
10707                } else {
10708                    name = args[opti];
10709                    opti++;
10710                    newArgs = new String[args.length - opti];
10711                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10712                            args.length - opti);
10713                }
10714                synchronized (this) {
10715                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10716                }
10717            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10718                synchronized (this) {
10719                    dumpOomLocked(fd, pw, args, opti, true);
10720                }
10721            } else if ("provider".equals(cmd)) {
10722                String[] newArgs;
10723                String name;
10724                if (opti >= args.length) {
10725                    name = null;
10726                    newArgs = EMPTY_STRING_ARRAY;
10727                } else {
10728                    name = args[opti];
10729                    opti++;
10730                    newArgs = new String[args.length - opti];
10731                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10732                }
10733                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10734                    pw.println("No providers match: " + name);
10735                    pw.println("Use -h for help.");
10736                }
10737            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10738                synchronized (this) {
10739                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10740                }
10741            } else if ("service".equals(cmd)) {
10742                String[] newArgs;
10743                String name;
10744                if (opti >= args.length) {
10745                    name = null;
10746                    newArgs = EMPTY_STRING_ARRAY;
10747                } else {
10748                    name = args[opti];
10749                    opti++;
10750                    newArgs = new String[args.length - opti];
10751                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10752                            args.length - opti);
10753                }
10754                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10755                    pw.println("No services match: " + name);
10756                    pw.println("Use -h for help.");
10757                }
10758            } else if ("package".equals(cmd)) {
10759                String[] newArgs;
10760                if (opti >= args.length) {
10761                    pw.println("package: no package name specified");
10762                    pw.println("Use -h for help.");
10763                } else {
10764                    dumpPackage = args[opti];
10765                    opti++;
10766                    newArgs = new String[args.length - opti];
10767                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10768                            args.length - opti);
10769                    args = newArgs;
10770                    opti = 0;
10771                    more = true;
10772                }
10773            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10774                synchronized (this) {
10775                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10776                }
10777            } else {
10778                // Dumping a single activity?
10779                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10780                    pw.println("Bad activity command, or no activities match: " + cmd);
10781                    pw.println("Use -h for help.");
10782                }
10783            }
10784            if (!more) {
10785                Binder.restoreCallingIdentity(origId);
10786                return;
10787            }
10788        }
10789
10790        // No piece of data specified, dump everything.
10791        synchronized (this) {
10792            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10793            pw.println();
10794            if (dumpAll) {
10795                pw.println("-------------------------------------------------------------------------------");
10796            }
10797            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10798            pw.println();
10799            if (dumpAll) {
10800                pw.println("-------------------------------------------------------------------------------");
10801            }
10802            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10803            pw.println();
10804            if (dumpAll) {
10805                pw.println("-------------------------------------------------------------------------------");
10806            }
10807            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10808            pw.println();
10809            if (dumpAll) {
10810                pw.println("-------------------------------------------------------------------------------");
10811            }
10812            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10813            pw.println();
10814            if (dumpAll) {
10815                pw.println("-------------------------------------------------------------------------------");
10816            }
10817            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10818        }
10819        Binder.restoreCallingIdentity(origId);
10820    }
10821
10822    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10823            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10824        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10825
10826        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10827                dumpPackage);
10828        boolean needSep = printedAnything;
10829
10830        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10831                dumpPackage, needSep, "  mFocusedActivity: ");
10832        if (printed) {
10833            printedAnything = true;
10834            needSep = false;
10835        }
10836
10837        if (dumpPackage == null) {
10838            if (needSep) {
10839                pw.println();
10840            }
10841            needSep = true;
10842            printedAnything = true;
10843            mStackSupervisor.dump(pw, "  ");
10844        }
10845
10846        if (mRecentTasks.size() > 0) {
10847            boolean printedHeader = false;
10848
10849            final int N = mRecentTasks.size();
10850            for (int i=0; i<N; i++) {
10851                TaskRecord tr = mRecentTasks.get(i);
10852                if (dumpPackage != null) {
10853                    if (tr.realActivity == null ||
10854                            !dumpPackage.equals(tr.realActivity)) {
10855                        continue;
10856                    }
10857                }
10858                if (!printedHeader) {
10859                    if (needSep) {
10860                        pw.println();
10861                    }
10862                    pw.println("  Recent tasks:");
10863                    printedHeader = true;
10864                    printedAnything = true;
10865                }
10866                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10867                        pw.println(tr);
10868                if (dumpAll) {
10869                    mRecentTasks.get(i).dump(pw, "    ");
10870                }
10871            }
10872        }
10873
10874        if (!printedAnything) {
10875            pw.println("  (nothing)");
10876        }
10877    }
10878
10879    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10880            int opti, boolean dumpAll, String dumpPackage) {
10881        boolean needSep = false;
10882        boolean printedAnything = false;
10883        int numPers = 0;
10884
10885        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10886
10887        if (dumpAll) {
10888            final int NP = mProcessNames.getMap().size();
10889            for (int ip=0; ip<NP; ip++) {
10890                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10891                final int NA = procs.size();
10892                for (int ia=0; ia<NA; ia++) {
10893                    ProcessRecord r = procs.valueAt(ia);
10894                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10895                        continue;
10896                    }
10897                    if (!needSep) {
10898                        pw.println("  All known processes:");
10899                        needSep = true;
10900                        printedAnything = true;
10901                    }
10902                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10903                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10904                        pw.print(" "); pw.println(r);
10905                    r.dump(pw, "    ");
10906                    if (r.persistent) {
10907                        numPers++;
10908                    }
10909                }
10910            }
10911        }
10912
10913        if (mIsolatedProcesses.size() > 0) {
10914            boolean printed = false;
10915            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10916                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10917                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10918                    continue;
10919                }
10920                if (!printed) {
10921                    if (needSep) {
10922                        pw.println();
10923                    }
10924                    pw.println("  Isolated process list (sorted by uid):");
10925                    printedAnything = true;
10926                    printed = true;
10927                    needSep = true;
10928                }
10929                pw.println(String.format("%sIsolated #%2d: %s",
10930                        "    ", i, r.toString()));
10931            }
10932        }
10933
10934        if (mLruProcesses.size() > 0) {
10935            if (needSep) {
10936                pw.println();
10937            }
10938            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10939                    pw.print(" total, non-act at ");
10940                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10941                    pw.print(", non-svc at ");
10942                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10943                    pw.println("):");
10944            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10945            needSep = true;
10946            printedAnything = true;
10947        }
10948
10949        if (dumpAll || dumpPackage != null) {
10950            synchronized (mPidsSelfLocked) {
10951                boolean printed = false;
10952                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10953                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10954                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10955                        continue;
10956                    }
10957                    if (!printed) {
10958                        if (needSep) pw.println();
10959                        needSep = true;
10960                        pw.println("  PID mappings:");
10961                        printed = true;
10962                        printedAnything = true;
10963                    }
10964                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10965                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10966                }
10967            }
10968        }
10969
10970        if (mForegroundProcesses.size() > 0) {
10971            synchronized (mPidsSelfLocked) {
10972                boolean printed = false;
10973                for (int i=0; i<mForegroundProcesses.size(); i++) {
10974                    ProcessRecord r = mPidsSelfLocked.get(
10975                            mForegroundProcesses.valueAt(i).pid);
10976                    if (dumpPackage != null && (r == null
10977                            || !r.pkgList.containsKey(dumpPackage))) {
10978                        continue;
10979                    }
10980                    if (!printed) {
10981                        if (needSep) pw.println();
10982                        needSep = true;
10983                        pw.println("  Foreground Processes:");
10984                        printed = true;
10985                        printedAnything = true;
10986                    }
10987                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10988                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10989                }
10990            }
10991        }
10992
10993        if (mPersistentStartingProcesses.size() > 0) {
10994            if (needSep) pw.println();
10995            needSep = true;
10996            printedAnything = true;
10997            pw.println("  Persisent processes that are starting:");
10998            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10999                    "Starting Norm", "Restarting PERS", dumpPackage);
11000        }
11001
11002        if (mRemovedProcesses.size() > 0) {
11003            if (needSep) pw.println();
11004            needSep = true;
11005            printedAnything = true;
11006            pw.println("  Processes that are being removed:");
11007            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11008                    "Removed Norm", "Removed PERS", dumpPackage);
11009        }
11010
11011        if (mProcessesOnHold.size() > 0) {
11012            if (needSep) pw.println();
11013            needSep = true;
11014            printedAnything = true;
11015            pw.println("  Processes that are on old until the system is ready:");
11016            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11017                    "OnHold Norm", "OnHold PERS", dumpPackage);
11018        }
11019
11020        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11021
11022        if (mProcessCrashTimes.getMap().size() > 0) {
11023            boolean printed = false;
11024            long now = SystemClock.uptimeMillis();
11025            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11026            final int NP = pmap.size();
11027            for (int ip=0; ip<NP; ip++) {
11028                String pname = pmap.keyAt(ip);
11029                SparseArray<Long> uids = pmap.valueAt(ip);
11030                final int N = uids.size();
11031                for (int i=0; i<N; i++) {
11032                    int puid = uids.keyAt(i);
11033                    ProcessRecord r = mProcessNames.get(pname, puid);
11034                    if (dumpPackage != null && (r == null
11035                            || !r.pkgList.containsKey(dumpPackage))) {
11036                        continue;
11037                    }
11038                    if (!printed) {
11039                        if (needSep) pw.println();
11040                        needSep = true;
11041                        pw.println("  Time since processes crashed:");
11042                        printed = true;
11043                        printedAnything = true;
11044                    }
11045                    pw.print("    Process "); pw.print(pname);
11046                            pw.print(" uid "); pw.print(puid);
11047                            pw.print(": last crashed ");
11048                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11049                            pw.println(" ago");
11050                }
11051            }
11052        }
11053
11054        if (mBadProcesses.getMap().size() > 0) {
11055            boolean printed = false;
11056            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11057            final int NP = pmap.size();
11058            for (int ip=0; ip<NP; ip++) {
11059                String pname = pmap.keyAt(ip);
11060                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11061                final int N = uids.size();
11062                for (int i=0; i<N; i++) {
11063                    int puid = uids.keyAt(i);
11064                    ProcessRecord r = mProcessNames.get(pname, puid);
11065                    if (dumpPackage != null && (r == null
11066                            || !r.pkgList.containsKey(dumpPackage))) {
11067                        continue;
11068                    }
11069                    if (!printed) {
11070                        if (needSep) pw.println();
11071                        needSep = true;
11072                        pw.println("  Bad processes:");
11073                        printedAnything = true;
11074                    }
11075                    BadProcessInfo info = uids.valueAt(i);
11076                    pw.print("    Bad process "); pw.print(pname);
11077                            pw.print(" uid "); pw.print(puid);
11078                            pw.print(": crashed at time "); pw.println(info.time);
11079                    if (info.shortMsg != null) {
11080                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11081                    }
11082                    if (info.longMsg != null) {
11083                        pw.print("      Long msg: "); pw.println(info.longMsg);
11084                    }
11085                    if (info.stack != null) {
11086                        pw.println("      Stack:");
11087                        int lastPos = 0;
11088                        for (int pos=0; pos<info.stack.length(); pos++) {
11089                            if (info.stack.charAt(pos) == '\n') {
11090                                pw.print("        ");
11091                                pw.write(info.stack, lastPos, pos-lastPos);
11092                                pw.println();
11093                                lastPos = pos+1;
11094                            }
11095                        }
11096                        if (lastPos < info.stack.length()) {
11097                            pw.print("        ");
11098                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11099                            pw.println();
11100                        }
11101                    }
11102                }
11103            }
11104        }
11105
11106        if (dumpPackage == null) {
11107            pw.println();
11108            needSep = false;
11109            pw.println("  mStartedUsers:");
11110            for (int i=0; i<mStartedUsers.size(); i++) {
11111                UserStartedState uss = mStartedUsers.valueAt(i);
11112                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11113                        pw.print(": "); uss.dump("", pw);
11114            }
11115            pw.print("  mStartedUserArray: [");
11116            for (int i=0; i<mStartedUserArray.length; i++) {
11117                if (i > 0) pw.print(", ");
11118                pw.print(mStartedUserArray[i]);
11119            }
11120            pw.println("]");
11121            pw.print("  mUserLru: [");
11122            for (int i=0; i<mUserLru.size(); i++) {
11123                if (i > 0) pw.print(", ");
11124                pw.print(mUserLru.get(i));
11125            }
11126            pw.println("]");
11127            if (dumpAll) {
11128                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11129            }
11130        }
11131        if (mHomeProcess != null && (dumpPackage == null
11132                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11133            if (needSep) {
11134                pw.println();
11135                needSep = false;
11136            }
11137            pw.println("  mHomeProcess: " + mHomeProcess);
11138        }
11139        if (mPreviousProcess != null && (dumpPackage == null
11140                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11141            if (needSep) {
11142                pw.println();
11143                needSep = false;
11144            }
11145            pw.println("  mPreviousProcess: " + mPreviousProcess);
11146        }
11147        if (dumpAll) {
11148            StringBuilder sb = new StringBuilder(128);
11149            sb.append("  mPreviousProcessVisibleTime: ");
11150            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11151            pw.println(sb);
11152        }
11153        if (mHeavyWeightProcess != null && (dumpPackage == null
11154                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11155            if (needSep) {
11156                pw.println();
11157                needSep = false;
11158            }
11159            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11160        }
11161        if (dumpPackage == null) {
11162            pw.println("  mConfiguration: " + mConfiguration);
11163        }
11164        if (dumpAll) {
11165            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11166            if (mCompatModePackages.getPackages().size() > 0) {
11167                boolean printed = false;
11168                for (Map.Entry<String, Integer> entry
11169                        : mCompatModePackages.getPackages().entrySet()) {
11170                    String pkg = entry.getKey();
11171                    int mode = entry.getValue();
11172                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11173                        continue;
11174                    }
11175                    if (!printed) {
11176                        pw.println("  mScreenCompatPackages:");
11177                        printed = true;
11178                    }
11179                    pw.print("    "); pw.print(pkg); pw.print(": ");
11180                            pw.print(mode); pw.println();
11181                }
11182            }
11183        }
11184        if (dumpPackage == null) {
11185            if (mSleeping || mWentToSleep || mLockScreenShown) {
11186                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11187                        + " mLockScreenShown " + mLockScreenShown);
11188            }
11189            if (mShuttingDown || mRunningVoice) {
11190                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11191            }
11192        }
11193        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11194                || mOrigWaitForDebugger) {
11195            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11196                    || dumpPackage.equals(mOrigDebugApp)) {
11197                if (needSep) {
11198                    pw.println();
11199                    needSep = false;
11200                }
11201                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11202                        + " mDebugTransient=" + mDebugTransient
11203                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11204            }
11205        }
11206        if (mOpenGlTraceApp != null) {
11207            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11208                if (needSep) {
11209                    pw.println();
11210                    needSep = false;
11211                }
11212                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11213            }
11214        }
11215        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11216                || mProfileFd != null) {
11217            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11218                if (needSep) {
11219                    pw.println();
11220                    needSep = false;
11221                }
11222                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11223                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11224                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11225                        + mAutoStopProfiler);
11226            }
11227        }
11228        if (dumpPackage == null) {
11229            if (mAlwaysFinishActivities || mController != null) {
11230                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11231                        + " mController=" + mController);
11232            }
11233            if (dumpAll) {
11234                pw.println("  Total persistent processes: " + numPers);
11235                pw.println("  mProcessesReady=" + mProcessesReady
11236                        + " mSystemReady=" + mSystemReady);
11237                pw.println("  mBooting=" + mBooting
11238                        + " mBooted=" + mBooted
11239                        + " mFactoryTest=" + mFactoryTest);
11240                pw.print("  mLastPowerCheckRealtime=");
11241                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11242                        pw.println("");
11243                pw.print("  mLastPowerCheckUptime=");
11244                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11245                        pw.println("");
11246                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11247                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11248                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11249                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11250                        + " (" + mLruProcesses.size() + " total)"
11251                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11252                        + " mNumServiceProcs=" + mNumServiceProcs
11253                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11254                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11255                        + " mLastMemoryLevel" + mLastMemoryLevel
11256                        + " mLastNumProcesses" + mLastNumProcesses);
11257                long now = SystemClock.uptimeMillis();
11258                pw.print("  mLastIdleTime=");
11259                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11260                        pw.print(" mLowRamSinceLastIdle=");
11261                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11262                        pw.println();
11263            }
11264        }
11265
11266        if (!printedAnything) {
11267            pw.println("  (nothing)");
11268        }
11269    }
11270
11271    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11272            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11273        if (mProcessesToGc.size() > 0) {
11274            boolean printed = false;
11275            long now = SystemClock.uptimeMillis();
11276            for (int i=0; i<mProcessesToGc.size(); i++) {
11277                ProcessRecord proc = mProcessesToGc.get(i);
11278                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11279                    continue;
11280                }
11281                if (!printed) {
11282                    if (needSep) pw.println();
11283                    needSep = true;
11284                    pw.println("  Processes that are waiting to GC:");
11285                    printed = true;
11286                }
11287                pw.print("    Process "); pw.println(proc);
11288                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11289                        pw.print(", last gced=");
11290                        pw.print(now-proc.lastRequestedGc);
11291                        pw.print(" ms ago, last lowMem=");
11292                        pw.print(now-proc.lastLowMemory);
11293                        pw.println(" ms ago");
11294
11295            }
11296        }
11297        return needSep;
11298    }
11299
11300    void printOomLevel(PrintWriter pw, String name, int adj) {
11301        pw.print("    ");
11302        if (adj >= 0) {
11303            pw.print(' ');
11304            if (adj < 10) pw.print(' ');
11305        } else {
11306            if (adj > -10) pw.print(' ');
11307        }
11308        pw.print(adj);
11309        pw.print(": ");
11310        pw.print(name);
11311        pw.print(" (");
11312        pw.print(mProcessList.getMemLevel(adj)/1024);
11313        pw.println(" kB)");
11314    }
11315
11316    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11317            int opti, boolean dumpAll) {
11318        boolean needSep = false;
11319
11320        if (mLruProcesses.size() > 0) {
11321            if (needSep) pw.println();
11322            needSep = true;
11323            pw.println("  OOM levels:");
11324            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11325            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11326            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11327            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11328            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11329            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11330            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11331            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11332            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11333            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11334            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11335            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11336            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11337
11338            if (needSep) pw.println();
11339            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11340                    pw.print(" total, non-act at ");
11341                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11342                    pw.print(", non-svc at ");
11343                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11344                    pw.println("):");
11345            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11346            needSep = true;
11347        }
11348
11349        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11350
11351        pw.println();
11352        pw.println("  mHomeProcess: " + mHomeProcess);
11353        pw.println("  mPreviousProcess: " + mPreviousProcess);
11354        if (mHeavyWeightProcess != null) {
11355            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11356        }
11357
11358        return true;
11359    }
11360
11361    /**
11362     * There are three ways to call this:
11363     *  - no provider specified: dump all the providers
11364     *  - a flattened component name that matched an existing provider was specified as the
11365     *    first arg: dump that one provider
11366     *  - the first arg isn't the flattened component name of an existing provider:
11367     *    dump all providers whose component contains the first arg as a substring
11368     */
11369    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11370            int opti, boolean dumpAll) {
11371        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11372    }
11373
11374    static class ItemMatcher {
11375        ArrayList<ComponentName> components;
11376        ArrayList<String> strings;
11377        ArrayList<Integer> objects;
11378        boolean all;
11379
11380        ItemMatcher() {
11381            all = true;
11382        }
11383
11384        void build(String name) {
11385            ComponentName componentName = ComponentName.unflattenFromString(name);
11386            if (componentName != null) {
11387                if (components == null) {
11388                    components = new ArrayList<ComponentName>();
11389                }
11390                components.add(componentName);
11391                all = false;
11392            } else {
11393                int objectId = 0;
11394                // Not a '/' separated full component name; maybe an object ID?
11395                try {
11396                    objectId = Integer.parseInt(name, 16);
11397                    if (objects == null) {
11398                        objects = new ArrayList<Integer>();
11399                    }
11400                    objects.add(objectId);
11401                    all = false;
11402                } catch (RuntimeException e) {
11403                    // Not an integer; just do string match.
11404                    if (strings == null) {
11405                        strings = new ArrayList<String>();
11406                    }
11407                    strings.add(name);
11408                    all = false;
11409                }
11410            }
11411        }
11412
11413        int build(String[] args, int opti) {
11414            for (; opti<args.length; opti++) {
11415                String name = args[opti];
11416                if ("--".equals(name)) {
11417                    return opti+1;
11418                }
11419                build(name);
11420            }
11421            return opti;
11422        }
11423
11424        boolean match(Object object, ComponentName comp) {
11425            if (all) {
11426                return true;
11427            }
11428            if (components != null) {
11429                for (int i=0; i<components.size(); i++) {
11430                    if (components.get(i).equals(comp)) {
11431                        return true;
11432                    }
11433                }
11434            }
11435            if (objects != null) {
11436                for (int i=0; i<objects.size(); i++) {
11437                    if (System.identityHashCode(object) == objects.get(i)) {
11438                        return true;
11439                    }
11440                }
11441            }
11442            if (strings != null) {
11443                String flat = comp.flattenToString();
11444                for (int i=0; i<strings.size(); i++) {
11445                    if (flat.contains(strings.get(i))) {
11446                        return true;
11447                    }
11448                }
11449            }
11450            return false;
11451        }
11452    }
11453
11454    /**
11455     * There are three things that cmd can be:
11456     *  - a flattened component name that matches an existing activity
11457     *  - the cmd arg isn't the flattened component name of an existing activity:
11458     *    dump all activity whose component contains the cmd as a substring
11459     *  - A hex number of the ActivityRecord object instance.
11460     */
11461    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11462            int opti, boolean dumpAll) {
11463        ArrayList<ActivityRecord> activities;
11464
11465        synchronized (this) {
11466            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11467        }
11468
11469        if (activities.size() <= 0) {
11470            return false;
11471        }
11472
11473        String[] newArgs = new String[args.length - opti];
11474        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11475
11476        TaskRecord lastTask = null;
11477        boolean needSep = false;
11478        for (int i=activities.size()-1; i>=0; i--) {
11479            ActivityRecord r = activities.get(i);
11480            if (needSep) {
11481                pw.println();
11482            }
11483            needSep = true;
11484            synchronized (this) {
11485                if (lastTask != r.task) {
11486                    lastTask = r.task;
11487                    pw.print("TASK "); pw.print(lastTask.affinity);
11488                            pw.print(" id="); pw.println(lastTask.taskId);
11489                    if (dumpAll) {
11490                        lastTask.dump(pw, "  ");
11491                    }
11492                }
11493            }
11494            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11495        }
11496        return true;
11497    }
11498
11499    /**
11500     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11501     * there is a thread associated with the activity.
11502     */
11503    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11504            final ActivityRecord r, String[] args, boolean dumpAll) {
11505        String innerPrefix = prefix + "  ";
11506        synchronized (this) {
11507            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11508                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11509                    pw.print(" pid=");
11510                    if (r.app != null) pw.println(r.app.pid);
11511                    else pw.println("(not running)");
11512            if (dumpAll) {
11513                r.dump(pw, innerPrefix);
11514            }
11515        }
11516        if (r.app != null && r.app.thread != null) {
11517            // flush anything that is already in the PrintWriter since the thread is going
11518            // to write to the file descriptor directly
11519            pw.flush();
11520            try {
11521                TransferPipe tp = new TransferPipe();
11522                try {
11523                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11524                            r.appToken, innerPrefix, args);
11525                    tp.go(fd);
11526                } finally {
11527                    tp.kill();
11528                }
11529            } catch (IOException e) {
11530                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11531            } catch (RemoteException e) {
11532                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11533            }
11534        }
11535    }
11536
11537    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11538            int opti, boolean dumpAll, String dumpPackage) {
11539        boolean needSep = false;
11540        boolean onlyHistory = false;
11541        boolean printedAnything = false;
11542
11543        if ("history".equals(dumpPackage)) {
11544            if (opti < args.length && "-s".equals(args[opti])) {
11545                dumpAll = false;
11546            }
11547            onlyHistory = true;
11548            dumpPackage = null;
11549        }
11550
11551        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11552        if (!onlyHistory && dumpAll) {
11553            if (mRegisteredReceivers.size() > 0) {
11554                boolean printed = false;
11555                Iterator it = mRegisteredReceivers.values().iterator();
11556                while (it.hasNext()) {
11557                    ReceiverList r = (ReceiverList)it.next();
11558                    if (dumpPackage != null && (r.app == null ||
11559                            !dumpPackage.equals(r.app.info.packageName))) {
11560                        continue;
11561                    }
11562                    if (!printed) {
11563                        pw.println("  Registered Receivers:");
11564                        needSep = true;
11565                        printed = true;
11566                        printedAnything = true;
11567                    }
11568                    pw.print("  * "); pw.println(r);
11569                    r.dump(pw, "    ");
11570                }
11571            }
11572
11573            if (mReceiverResolver.dump(pw, needSep ?
11574                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11575                    "    ", dumpPackage, false)) {
11576                needSep = true;
11577                printedAnything = true;
11578            }
11579        }
11580
11581        for (BroadcastQueue q : mBroadcastQueues) {
11582            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11583            printedAnything |= needSep;
11584        }
11585
11586        needSep = true;
11587
11588        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11589            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11590                if (needSep) {
11591                    pw.println();
11592                }
11593                needSep = true;
11594                printedAnything = true;
11595                pw.print("  Sticky broadcasts for user ");
11596                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11597                StringBuilder sb = new StringBuilder(128);
11598                for (Map.Entry<String, ArrayList<Intent>> ent
11599                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11600                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11601                    if (dumpAll) {
11602                        pw.println(":");
11603                        ArrayList<Intent> intents = ent.getValue();
11604                        final int N = intents.size();
11605                        for (int i=0; i<N; i++) {
11606                            sb.setLength(0);
11607                            sb.append("    Intent: ");
11608                            intents.get(i).toShortString(sb, false, true, false, false);
11609                            pw.println(sb.toString());
11610                            Bundle bundle = intents.get(i).getExtras();
11611                            if (bundle != null) {
11612                                pw.print("      ");
11613                                pw.println(bundle.toString());
11614                            }
11615                        }
11616                    } else {
11617                        pw.println("");
11618                    }
11619                }
11620            }
11621        }
11622
11623        if (!onlyHistory && dumpAll) {
11624            pw.println();
11625            for (BroadcastQueue queue : mBroadcastQueues) {
11626                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11627                        + queue.mBroadcastsScheduled);
11628            }
11629            pw.println("  mHandler:");
11630            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11631            needSep = true;
11632            printedAnything = true;
11633        }
11634
11635        if (!printedAnything) {
11636            pw.println("  (nothing)");
11637        }
11638    }
11639
11640    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11641            int opti, boolean dumpAll, String dumpPackage) {
11642        boolean needSep;
11643        boolean printedAnything = false;
11644
11645        ItemMatcher matcher = new ItemMatcher();
11646        matcher.build(args, opti);
11647
11648        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11649
11650        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11651        printedAnything |= needSep;
11652
11653        if (mLaunchingProviders.size() > 0) {
11654            boolean printed = false;
11655            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11656                ContentProviderRecord r = mLaunchingProviders.get(i);
11657                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11658                    continue;
11659                }
11660                if (!printed) {
11661                    if (needSep) pw.println();
11662                    needSep = true;
11663                    pw.println("  Launching content providers:");
11664                    printed = true;
11665                    printedAnything = true;
11666                }
11667                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11668                        pw.println(r);
11669            }
11670        }
11671
11672        if (mGrantedUriPermissions.size() > 0) {
11673            boolean printed = false;
11674            int dumpUid = -2;
11675            if (dumpPackage != null) {
11676                try {
11677                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11678                } catch (NameNotFoundException e) {
11679                    dumpUid = -1;
11680                }
11681            }
11682            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11683                int uid = mGrantedUriPermissions.keyAt(i);
11684                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11685                    continue;
11686                }
11687                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11688                if (!printed) {
11689                    if (needSep) pw.println();
11690                    needSep = true;
11691                    pw.println("  Granted Uri Permissions:");
11692                    printed = true;
11693                    printedAnything = true;
11694                }
11695                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11696                for (UriPermission perm : perms.values()) {
11697                    pw.print("    "); pw.println(perm);
11698                    if (dumpAll) {
11699                        perm.dump(pw, "      ");
11700                    }
11701                }
11702            }
11703        }
11704
11705        if (!printedAnything) {
11706            pw.println("  (nothing)");
11707        }
11708    }
11709
11710    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11711            int opti, boolean dumpAll, String dumpPackage) {
11712        boolean printed = false;
11713
11714        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11715
11716        if (mIntentSenderRecords.size() > 0) {
11717            Iterator<WeakReference<PendingIntentRecord>> it
11718                    = mIntentSenderRecords.values().iterator();
11719            while (it.hasNext()) {
11720                WeakReference<PendingIntentRecord> ref = it.next();
11721                PendingIntentRecord rec = ref != null ? ref.get(): null;
11722                if (dumpPackage != null && (rec == null
11723                        || !dumpPackage.equals(rec.key.packageName))) {
11724                    continue;
11725                }
11726                printed = true;
11727                if (rec != null) {
11728                    pw.print("  * "); pw.println(rec);
11729                    if (dumpAll) {
11730                        rec.dump(pw, "    ");
11731                    }
11732                } else {
11733                    pw.print("  * "); pw.println(ref);
11734                }
11735            }
11736        }
11737
11738        if (!printed) {
11739            pw.println("  (nothing)");
11740        }
11741    }
11742
11743    private static final int dumpProcessList(PrintWriter pw,
11744            ActivityManagerService service, List list,
11745            String prefix, String normalLabel, String persistentLabel,
11746            String dumpPackage) {
11747        int numPers = 0;
11748        final int N = list.size()-1;
11749        for (int i=N; i>=0; i--) {
11750            ProcessRecord r = (ProcessRecord)list.get(i);
11751            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11752                continue;
11753            }
11754            pw.println(String.format("%s%s #%2d: %s",
11755                    prefix, (r.persistent ? persistentLabel : normalLabel),
11756                    i, r.toString()));
11757            if (r.persistent) {
11758                numPers++;
11759            }
11760        }
11761        return numPers;
11762    }
11763
11764    private static final boolean dumpProcessOomList(PrintWriter pw,
11765            ActivityManagerService service, List<ProcessRecord> origList,
11766            String prefix, String normalLabel, String persistentLabel,
11767            boolean inclDetails, String dumpPackage) {
11768
11769        ArrayList<Pair<ProcessRecord, Integer>> list
11770                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11771        for (int i=0; i<origList.size(); i++) {
11772            ProcessRecord r = origList.get(i);
11773            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11774                continue;
11775            }
11776            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11777        }
11778
11779        if (list.size() <= 0) {
11780            return false;
11781        }
11782
11783        Comparator<Pair<ProcessRecord, Integer>> comparator
11784                = new Comparator<Pair<ProcessRecord, Integer>>() {
11785            @Override
11786            public int compare(Pair<ProcessRecord, Integer> object1,
11787                    Pair<ProcessRecord, Integer> object2) {
11788                if (object1.first.setAdj != object2.first.setAdj) {
11789                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11790                }
11791                if (object1.second.intValue() != object2.second.intValue()) {
11792                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11793                }
11794                return 0;
11795            }
11796        };
11797
11798        Collections.sort(list, comparator);
11799
11800        final long curRealtime = SystemClock.elapsedRealtime();
11801        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11802        final long curUptime = SystemClock.uptimeMillis();
11803        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11804
11805        for (int i=list.size()-1; i>=0; i--) {
11806            ProcessRecord r = list.get(i).first;
11807            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11808            char schedGroup;
11809            switch (r.setSchedGroup) {
11810                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11811                    schedGroup = 'B';
11812                    break;
11813                case Process.THREAD_GROUP_DEFAULT:
11814                    schedGroup = 'F';
11815                    break;
11816                default:
11817                    schedGroup = '?';
11818                    break;
11819            }
11820            char foreground;
11821            if (r.foregroundActivities) {
11822                foreground = 'A';
11823            } else if (r.foregroundServices) {
11824                foreground = 'S';
11825            } else {
11826                foreground = ' ';
11827            }
11828            String procState = ProcessList.makeProcStateString(r.curProcState);
11829            pw.print(prefix);
11830            pw.print(r.persistent ? persistentLabel : normalLabel);
11831            pw.print(" #");
11832            int num = (origList.size()-1)-list.get(i).second;
11833            if (num < 10) pw.print(' ');
11834            pw.print(num);
11835            pw.print(": ");
11836            pw.print(oomAdj);
11837            pw.print(' ');
11838            pw.print(schedGroup);
11839            pw.print('/');
11840            pw.print(foreground);
11841            pw.print('/');
11842            pw.print(procState);
11843            pw.print(" trm:");
11844            if (r.trimMemoryLevel < 10) pw.print(' ');
11845            pw.print(r.trimMemoryLevel);
11846            pw.print(' ');
11847            pw.print(r.toShortString());
11848            pw.print(" (");
11849            pw.print(r.adjType);
11850            pw.println(')');
11851            if (r.adjSource != null || r.adjTarget != null) {
11852                pw.print(prefix);
11853                pw.print("    ");
11854                if (r.adjTarget instanceof ComponentName) {
11855                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11856                } else if (r.adjTarget != null) {
11857                    pw.print(r.adjTarget.toString());
11858                } else {
11859                    pw.print("{null}");
11860                }
11861                pw.print("<=");
11862                if (r.adjSource instanceof ProcessRecord) {
11863                    pw.print("Proc{");
11864                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11865                    pw.println("}");
11866                } else if (r.adjSource != null) {
11867                    pw.println(r.adjSource.toString());
11868                } else {
11869                    pw.println("{null}");
11870                }
11871            }
11872            if (inclDetails) {
11873                pw.print(prefix);
11874                pw.print("    ");
11875                pw.print("oom: max="); pw.print(r.maxAdj);
11876                pw.print(" curRaw="); pw.print(r.curRawAdj);
11877                pw.print(" setRaw="); pw.print(r.setRawAdj);
11878                pw.print(" cur="); pw.print(r.curAdj);
11879                pw.print(" set="); pw.println(r.setAdj);
11880                pw.print(prefix);
11881                pw.print("    ");
11882                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11883                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11884                pw.print(" lastPss="); pw.print(r.lastPss);
11885                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11886                pw.print(prefix);
11887                pw.print("    ");
11888                pw.print("keeping="); pw.print(r.keeping);
11889                pw.print(" cached="); pw.print(r.cached);
11890                pw.print(" empty="); pw.print(r.empty);
11891                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11892
11893                if (!r.keeping) {
11894                    if (r.lastWakeTime != 0) {
11895                        long wtime;
11896                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11897                        synchronized (stats) {
11898                            wtime = stats.getProcessWakeTime(r.info.uid,
11899                                    r.pid, curRealtime);
11900                        }
11901                        long timeUsed = wtime - r.lastWakeTime;
11902                        pw.print(prefix);
11903                        pw.print("    ");
11904                        pw.print("keep awake over ");
11905                        TimeUtils.formatDuration(realtimeSince, pw);
11906                        pw.print(" used ");
11907                        TimeUtils.formatDuration(timeUsed, pw);
11908                        pw.print(" (");
11909                        pw.print((timeUsed*100)/realtimeSince);
11910                        pw.println("%)");
11911                    }
11912                    if (r.lastCpuTime != 0) {
11913                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11914                        pw.print(prefix);
11915                        pw.print("    ");
11916                        pw.print("run cpu over ");
11917                        TimeUtils.formatDuration(uptimeSince, pw);
11918                        pw.print(" used ");
11919                        TimeUtils.formatDuration(timeUsed, pw);
11920                        pw.print(" (");
11921                        pw.print((timeUsed*100)/uptimeSince);
11922                        pw.println("%)");
11923                    }
11924                }
11925            }
11926        }
11927        return true;
11928    }
11929
11930    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11931        ArrayList<ProcessRecord> procs;
11932        synchronized (this) {
11933            if (args != null && args.length > start
11934                    && args[start].charAt(0) != '-') {
11935                procs = new ArrayList<ProcessRecord>();
11936                int pid = -1;
11937                try {
11938                    pid = Integer.parseInt(args[start]);
11939                } catch (NumberFormatException e) {
11940                }
11941                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11942                    ProcessRecord proc = mLruProcesses.get(i);
11943                    if (proc.pid == pid) {
11944                        procs.add(proc);
11945                    } else if (proc.processName.equals(args[start])) {
11946                        procs.add(proc);
11947                    }
11948                }
11949                if (procs.size() <= 0) {
11950                    return null;
11951                }
11952            } else {
11953                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11954            }
11955        }
11956        return procs;
11957    }
11958
11959    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11960            PrintWriter pw, String[] args) {
11961        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11962        if (procs == null) {
11963            pw.println("No process found for: " + args[0]);
11964            return;
11965        }
11966
11967        long uptime = SystemClock.uptimeMillis();
11968        long realtime = SystemClock.elapsedRealtime();
11969        pw.println("Applications Graphics Acceleration Info:");
11970        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11971
11972        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11973            ProcessRecord r = procs.get(i);
11974            if (r.thread != null) {
11975                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11976                pw.flush();
11977                try {
11978                    TransferPipe tp = new TransferPipe();
11979                    try {
11980                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11981                        tp.go(fd);
11982                    } finally {
11983                        tp.kill();
11984                    }
11985                } catch (IOException e) {
11986                    pw.println("Failure while dumping the app: " + r);
11987                    pw.flush();
11988                } catch (RemoteException e) {
11989                    pw.println("Got a RemoteException while dumping the app " + r);
11990                    pw.flush();
11991                }
11992            }
11993        }
11994    }
11995
11996    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11997        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11998        if (procs == null) {
11999            pw.println("No process found for: " + args[0]);
12000            return;
12001        }
12002
12003        pw.println("Applications Database Info:");
12004
12005        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12006            ProcessRecord r = procs.get(i);
12007            if (r.thread != null) {
12008                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12009                pw.flush();
12010                try {
12011                    TransferPipe tp = new TransferPipe();
12012                    try {
12013                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12014                        tp.go(fd);
12015                    } finally {
12016                        tp.kill();
12017                    }
12018                } catch (IOException e) {
12019                    pw.println("Failure while dumping the app: " + r);
12020                    pw.flush();
12021                } catch (RemoteException e) {
12022                    pw.println("Got a RemoteException while dumping the app " + r);
12023                    pw.flush();
12024                }
12025            }
12026        }
12027    }
12028
12029    final static class MemItem {
12030        final boolean isProc;
12031        final String label;
12032        final String shortLabel;
12033        final long pss;
12034        final int id;
12035        final boolean hasActivities;
12036        ArrayList<MemItem> subitems;
12037
12038        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12039                boolean _hasActivities) {
12040            isProc = true;
12041            label = _label;
12042            shortLabel = _shortLabel;
12043            pss = _pss;
12044            id = _id;
12045            hasActivities = _hasActivities;
12046        }
12047
12048        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12049            isProc = false;
12050            label = _label;
12051            shortLabel = _shortLabel;
12052            pss = _pss;
12053            id = _id;
12054            hasActivities = false;
12055        }
12056    }
12057
12058    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12059            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12060        if (sort && !isCompact) {
12061            Collections.sort(items, new Comparator<MemItem>() {
12062                @Override
12063                public int compare(MemItem lhs, MemItem rhs) {
12064                    if (lhs.pss < rhs.pss) {
12065                        return 1;
12066                    } else if (lhs.pss > rhs.pss) {
12067                        return -1;
12068                    }
12069                    return 0;
12070                }
12071            });
12072        }
12073
12074        for (int i=0; i<items.size(); i++) {
12075            MemItem mi = items.get(i);
12076            if (!isCompact) {
12077                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12078            } else if (mi.isProc) {
12079                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12080                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12081                pw.println(mi.hasActivities ? ",a" : ",e");
12082            } else {
12083                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12084                pw.println(mi.pss);
12085            }
12086            if (mi.subitems != null) {
12087                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12088                        true, isCompact);
12089            }
12090        }
12091    }
12092
12093    // These are in KB.
12094    static final long[] DUMP_MEM_BUCKETS = new long[] {
12095        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12096        120*1024, 160*1024, 200*1024,
12097        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12098        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12099    };
12100
12101    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12102            boolean stackLike) {
12103        int start = label.lastIndexOf('.');
12104        if (start >= 0) start++;
12105        else start = 0;
12106        int end = label.length();
12107        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12108            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12109                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12110                out.append(bucket);
12111                out.append(stackLike ? "MB." : "MB ");
12112                out.append(label, start, end);
12113                return;
12114            }
12115        }
12116        out.append(memKB/1024);
12117        out.append(stackLike ? "MB." : "MB ");
12118        out.append(label, start, end);
12119    }
12120
12121    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12122            ProcessList.NATIVE_ADJ,
12123            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12124            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12125            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12126            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12127            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12128    };
12129    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12130            "Native",
12131            "System", "Persistent", "Foreground",
12132            "Visible", "Perceptible",
12133            "Heavy Weight", "Backup",
12134            "A Services", "Home",
12135            "Previous", "B Services", "Cached"
12136    };
12137    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12138            "native",
12139            "sys", "pers", "fore",
12140            "vis", "percept",
12141            "heavy", "backup",
12142            "servicea", "home",
12143            "prev", "serviceb", "cached"
12144    };
12145
12146    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12147            long realtime, boolean isCheckinRequest, boolean isCompact) {
12148        if (isCheckinRequest || isCompact) {
12149            // short checkin version
12150            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12151        } else {
12152            pw.println("Applications Memory Usage (kB):");
12153            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12154        }
12155    }
12156
12157    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12158            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12159        boolean dumpDetails = false;
12160        boolean dumpFullDetails = false;
12161        boolean dumpDalvik = false;
12162        boolean oomOnly = false;
12163        boolean isCompact = false;
12164        boolean localOnly = false;
12165
12166        int opti = 0;
12167        while (opti < args.length) {
12168            String opt = args[opti];
12169            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12170                break;
12171            }
12172            opti++;
12173            if ("-a".equals(opt)) {
12174                dumpDetails = true;
12175                dumpFullDetails = true;
12176                dumpDalvik = true;
12177            } else if ("-d".equals(opt)) {
12178                dumpDalvik = true;
12179            } else if ("-c".equals(opt)) {
12180                isCompact = true;
12181            } else if ("--oom".equals(opt)) {
12182                oomOnly = true;
12183            } else if ("--local".equals(opt)) {
12184                localOnly = true;
12185            } else if ("-h".equals(opt)) {
12186                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12187                pw.println("  -a: include all available information for each process.");
12188                pw.println("  -d: include dalvik details when dumping process details.");
12189                pw.println("  -c: dump in a compact machine-parseable representation.");
12190                pw.println("  --oom: only show processes organized by oom adj.");
12191                pw.println("  --local: only collect details locally, don't call process.");
12192                pw.println("If [process] is specified it can be the name or ");
12193                pw.println("pid of a specific process to dump.");
12194                return;
12195            } else {
12196                pw.println("Unknown argument: " + opt + "; use -h for help");
12197            }
12198        }
12199
12200        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12201        long uptime = SystemClock.uptimeMillis();
12202        long realtime = SystemClock.elapsedRealtime();
12203        final long[] tmpLong = new long[1];
12204
12205        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12206        if (procs == null) {
12207            // No Java processes.  Maybe they want to print a native process.
12208            if (args != null && args.length > opti
12209                    && args[opti].charAt(0) != '-') {
12210                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12211                        = new ArrayList<ProcessCpuTracker.Stats>();
12212                updateCpuStatsNow();
12213                int findPid = -1;
12214                try {
12215                    findPid = Integer.parseInt(args[opti]);
12216                } catch (NumberFormatException e) {
12217                }
12218                synchronized (mProcessCpuThread) {
12219                    final int N = mProcessCpuTracker.countStats();
12220                    for (int i=0; i<N; i++) {
12221                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12222                        if (st.pid == findPid || (st.baseName != null
12223                                && st.baseName.equals(args[opti]))) {
12224                            nativeProcs.add(st);
12225                        }
12226                    }
12227                }
12228                if (nativeProcs.size() > 0) {
12229                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12230                            isCompact);
12231                    Debug.MemoryInfo mi = null;
12232                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12233                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12234                        final int pid = r.pid;
12235                        if (!isCheckinRequest && dumpDetails) {
12236                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12237                        }
12238                        if (mi == null) {
12239                            mi = new Debug.MemoryInfo();
12240                        }
12241                        if (dumpDetails || (!brief && !oomOnly)) {
12242                            Debug.getMemoryInfo(pid, mi);
12243                        } else {
12244                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12245                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12246                        }
12247                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12248                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12249                        if (isCheckinRequest) {
12250                            pw.println();
12251                        }
12252                    }
12253                    return;
12254                }
12255            }
12256            pw.println("No process found for: " + args[opti]);
12257            return;
12258        }
12259
12260        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12261            dumpDetails = true;
12262        }
12263
12264        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12265
12266        String[] innerArgs = new String[args.length-opti];
12267        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12268
12269        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12270        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12271        long nativePss=0, dalvikPss=0, otherPss=0;
12272        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12273
12274        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12275        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12276                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12277
12278        long totalPss = 0;
12279        long cachedPss = 0;
12280
12281        Debug.MemoryInfo mi = null;
12282        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12283            final ProcessRecord r = procs.get(i);
12284            final IApplicationThread thread;
12285            final int pid;
12286            final int oomAdj;
12287            final boolean hasActivities;
12288            synchronized (this) {
12289                thread = r.thread;
12290                pid = r.pid;
12291                oomAdj = r.getSetAdjWithServices();
12292                hasActivities = r.activities.size() > 0;
12293            }
12294            if (thread != null) {
12295                if (!isCheckinRequest && dumpDetails) {
12296                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12297                }
12298                if (mi == null) {
12299                    mi = new Debug.MemoryInfo();
12300                }
12301                if (dumpDetails || (!brief && !oomOnly)) {
12302                    Debug.getMemoryInfo(pid, mi);
12303                } else {
12304                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12305                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12306                }
12307                if (dumpDetails) {
12308                    if (localOnly) {
12309                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12310                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12311                        if (isCheckinRequest) {
12312                            pw.println();
12313                        }
12314                    } else {
12315                        try {
12316                            pw.flush();
12317                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12318                                    dumpDalvik, innerArgs);
12319                        } catch (RemoteException e) {
12320                            if (!isCheckinRequest) {
12321                                pw.println("Got RemoteException!");
12322                                pw.flush();
12323                            }
12324                        }
12325                    }
12326                }
12327
12328                final long myTotalPss = mi.getTotalPss();
12329                final long myTotalUss = mi.getTotalUss();
12330
12331                synchronized (this) {
12332                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12333                        // Record this for posterity if the process has been stable.
12334                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12335                    }
12336                }
12337
12338                if (!isCheckinRequest && mi != null) {
12339                    totalPss += myTotalPss;
12340                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12341                            (hasActivities ? " / activities)" : ")"),
12342                            r.processName, myTotalPss, pid, hasActivities);
12343                    procMems.add(pssItem);
12344                    procMemsMap.put(pid, pssItem);
12345
12346                    nativePss += mi.nativePss;
12347                    dalvikPss += mi.dalvikPss;
12348                    otherPss += mi.otherPss;
12349                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12350                        long mem = mi.getOtherPss(j);
12351                        miscPss[j] += mem;
12352                        otherPss -= mem;
12353                    }
12354
12355                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12356                        cachedPss += myTotalPss;
12357                    }
12358
12359                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12360                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12361                                || oomIndex == (oomPss.length-1)) {
12362                            oomPss[oomIndex] += myTotalPss;
12363                            if (oomProcs[oomIndex] == null) {
12364                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12365                            }
12366                            oomProcs[oomIndex].add(pssItem);
12367                            break;
12368                        }
12369                    }
12370                }
12371            }
12372        }
12373
12374        if (!isCheckinRequest && procs.size() > 1) {
12375            // If we are showing aggregations, also look for native processes to
12376            // include so that our aggregations are more accurate.
12377            updateCpuStatsNow();
12378            synchronized (mProcessCpuThread) {
12379                final int N = mProcessCpuTracker.countStats();
12380                for (int i=0; i<N; i++) {
12381                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12382                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12383                        if (mi == null) {
12384                            mi = new Debug.MemoryInfo();
12385                        }
12386                        if (!brief && !oomOnly) {
12387                            Debug.getMemoryInfo(st.pid, mi);
12388                        } else {
12389                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12390                            mi.nativePrivateDirty = (int)tmpLong[0];
12391                        }
12392
12393                        final long myTotalPss = mi.getTotalPss();
12394                        totalPss += myTotalPss;
12395
12396                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12397                                st.name, myTotalPss, st.pid, false);
12398                        procMems.add(pssItem);
12399
12400                        nativePss += mi.nativePss;
12401                        dalvikPss += mi.dalvikPss;
12402                        otherPss += mi.otherPss;
12403                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12404                            long mem = mi.getOtherPss(j);
12405                            miscPss[j] += mem;
12406                            otherPss -= mem;
12407                        }
12408                        oomPss[0] += myTotalPss;
12409                        if (oomProcs[0] == null) {
12410                            oomProcs[0] = new ArrayList<MemItem>();
12411                        }
12412                        oomProcs[0].add(pssItem);
12413                    }
12414                }
12415            }
12416
12417            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12418
12419            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12420            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12421            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12422            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12423                String label = Debug.MemoryInfo.getOtherLabel(j);
12424                catMems.add(new MemItem(label, label, miscPss[j], j));
12425            }
12426
12427            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12428            for (int j=0; j<oomPss.length; j++) {
12429                if (oomPss[j] != 0) {
12430                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12431                            : DUMP_MEM_OOM_LABEL[j];
12432                    MemItem item = new MemItem(label, label, oomPss[j],
12433                            DUMP_MEM_OOM_ADJ[j]);
12434                    item.subitems = oomProcs[j];
12435                    oomMems.add(item);
12436                }
12437            }
12438
12439            if (!brief && !oomOnly && !isCompact) {
12440                pw.println();
12441                pw.println("Total PSS by process:");
12442                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12443                pw.println();
12444            }
12445            if (!isCompact) {
12446                pw.println("Total PSS by OOM adjustment:");
12447            }
12448            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12449            if (!brief && !oomOnly) {
12450                PrintWriter out = categoryPw != null ? categoryPw : pw;
12451                if (!isCompact) {
12452                    out.println();
12453                    out.println("Total PSS by category:");
12454                }
12455                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12456            }
12457            if (!isCompact) {
12458                pw.println();
12459            }
12460            MemInfoReader memInfo = new MemInfoReader();
12461            memInfo.readMemInfo();
12462            if (!brief) {
12463                if (!isCompact) {
12464                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12465                    pw.print(" kB (status ");
12466                    switch (mLastMemoryLevel) {
12467                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12468                            pw.println("normal)");
12469                            break;
12470                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12471                            pw.println("moderate)");
12472                            break;
12473                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12474                            pw.println("low)");
12475                            break;
12476                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12477                            pw.println("critical)");
12478                            break;
12479                        default:
12480                            pw.print(mLastMemoryLevel);
12481                            pw.println(")");
12482                            break;
12483                    }
12484                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12485                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12486                            pw.print(cachedPss); pw.print(" cached pss + ");
12487                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12488                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12489                } else {
12490                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12491                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12492                            + memInfo.getFreeSizeKb()); pw.print(",");
12493                    pw.println(totalPss - cachedPss);
12494                }
12495            }
12496            if (!isCompact) {
12497                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12498                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12499                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12500                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12501                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12502                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12503                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12504                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12505                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12506                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12507                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12508            }
12509            if (!brief) {
12510                if (memInfo.getZramTotalSizeKb() != 0) {
12511                    if (!isCompact) {
12512                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12513                                pw.print(" kB physical used for ");
12514                                pw.print(memInfo.getSwapTotalSizeKb()
12515                                        - memInfo.getSwapFreeSizeKb());
12516                                pw.print(" kB in swap (");
12517                                pw.print(memInfo.getSwapTotalSizeKb());
12518                                pw.println(" kB total swap)");
12519                    } else {
12520                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12521                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12522                                pw.println(memInfo.getSwapFreeSizeKb());
12523                    }
12524                }
12525                final int[] SINGLE_LONG_FORMAT = new int[] {
12526                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12527                };
12528                long[] longOut = new long[1];
12529                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12530                        SINGLE_LONG_FORMAT, null, longOut, null);
12531                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12532                longOut[0] = 0;
12533                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12534                        SINGLE_LONG_FORMAT, null, longOut, null);
12535                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12536                longOut[0] = 0;
12537                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12538                        SINGLE_LONG_FORMAT, null, longOut, null);
12539                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12540                longOut[0] = 0;
12541                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12542                        SINGLE_LONG_FORMAT, null, longOut, null);
12543                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12544                if (!isCompact) {
12545                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12546                        pw.print("      KSM: "); pw.print(sharing);
12547                                pw.print(" kB saved from shared ");
12548                                pw.print(shared); pw.println(" kB");
12549                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12550                                pw.print(voltile); pw.println(" kB volatile");
12551                    }
12552                    pw.print("   Tuning: ");
12553                    pw.print(ActivityManager.staticGetMemoryClass());
12554                    pw.print(" (large ");
12555                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12556                    pw.print("), oom ");
12557                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12558                    pw.print(" kB");
12559                    pw.print(", restore limit ");
12560                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12561                    pw.print(" kB");
12562                    if (ActivityManager.isLowRamDeviceStatic()) {
12563                        pw.print(" (low-ram)");
12564                    }
12565                    if (ActivityManager.isHighEndGfx()) {
12566                        pw.print(" (high-end-gfx)");
12567                    }
12568                    pw.println();
12569                } else {
12570                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12571                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12572                    pw.println(voltile);
12573                    pw.print("tuning,");
12574                    pw.print(ActivityManager.staticGetMemoryClass());
12575                    pw.print(',');
12576                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12577                    pw.print(',');
12578                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
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                }
12587            }
12588        }
12589    }
12590
12591    /**
12592     * Searches array of arguments for the specified string
12593     * @param args array of argument strings
12594     * @param value value to search for
12595     * @return true if the value is contained in the array
12596     */
12597    private static boolean scanArgs(String[] args, String value) {
12598        if (args != null) {
12599            for (String arg : args) {
12600                if (value.equals(arg)) {
12601                    return true;
12602                }
12603            }
12604        }
12605        return false;
12606    }
12607
12608    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12609            ContentProviderRecord cpr, boolean always) {
12610        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12611
12612        if (!inLaunching || always) {
12613            synchronized (cpr) {
12614                cpr.launchingApp = null;
12615                cpr.notifyAll();
12616            }
12617            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12618            String names[] = cpr.info.authority.split(";");
12619            for (int j = 0; j < names.length; j++) {
12620                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12621            }
12622        }
12623
12624        for (int i=0; i<cpr.connections.size(); i++) {
12625            ContentProviderConnection conn = cpr.connections.get(i);
12626            if (conn.waiting) {
12627                // If this connection is waiting for the provider, then we don't
12628                // need to mess with its process unless we are always removing
12629                // or for some reason the provider is not currently launching.
12630                if (inLaunching && !always) {
12631                    continue;
12632                }
12633            }
12634            ProcessRecord capp = conn.client;
12635            conn.dead = true;
12636            if (conn.stableCount > 0) {
12637                if (!capp.persistent && capp.thread != null
12638                        && capp.pid != 0
12639                        && capp.pid != MY_PID) {
12640                    killUnneededProcessLocked(capp, "depends on provider "
12641                            + cpr.name.flattenToShortString()
12642                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12643                }
12644            } else if (capp.thread != null && conn.provider.provider != null) {
12645                try {
12646                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12647                } catch (RemoteException e) {
12648                }
12649                // In the protocol here, we don't expect the client to correctly
12650                // clean up this connection, we'll just remove it.
12651                cpr.connections.remove(i);
12652                conn.client.conProviders.remove(conn);
12653            }
12654        }
12655
12656        if (inLaunching && always) {
12657            mLaunchingProviders.remove(cpr);
12658        }
12659        return inLaunching;
12660    }
12661
12662    /**
12663     * Main code for cleaning up a process when it has gone away.  This is
12664     * called both as a result of the process dying, or directly when stopping
12665     * a process when running in single process mode.
12666     */
12667    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12668            boolean restarting, boolean allowRestart, int index) {
12669        if (index >= 0) {
12670            removeLruProcessLocked(app);
12671            ProcessList.remove(app.pid);
12672        }
12673
12674        mProcessesToGc.remove(app);
12675        mPendingPssProcesses.remove(app);
12676
12677        // Dismiss any open dialogs.
12678        if (app.crashDialog != null && !app.forceCrashReport) {
12679            app.crashDialog.dismiss();
12680            app.crashDialog = null;
12681        }
12682        if (app.anrDialog != null) {
12683            app.anrDialog.dismiss();
12684            app.anrDialog = null;
12685        }
12686        if (app.waitDialog != null) {
12687            app.waitDialog.dismiss();
12688            app.waitDialog = null;
12689        }
12690
12691        app.crashing = false;
12692        app.notResponding = false;
12693
12694        app.resetPackageList(mProcessStats);
12695        app.unlinkDeathRecipient();
12696        app.makeInactive(mProcessStats);
12697        app.forcingToForeground = null;
12698        updateProcessForegroundLocked(app, false, false);
12699        app.foregroundActivities = false;
12700        app.hasShownUi = false;
12701        app.treatLikeActivity = false;
12702        app.hasAboveClient = false;
12703        app.hasClientActivities = false;
12704
12705        mServices.killServicesLocked(app, allowRestart);
12706
12707        boolean restart = false;
12708
12709        // Remove published content providers.
12710        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12711            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12712            final boolean always = app.bad || !allowRestart;
12713            if (removeDyingProviderLocked(app, cpr, always) || always) {
12714                // We left the provider in the launching list, need to
12715                // restart it.
12716                restart = true;
12717            }
12718
12719            cpr.provider = null;
12720            cpr.proc = null;
12721        }
12722        app.pubProviders.clear();
12723
12724        // Take care of any launching providers waiting for this process.
12725        if (checkAppInLaunchingProvidersLocked(app, false)) {
12726            restart = true;
12727        }
12728
12729        // Unregister from connected content providers.
12730        if (!app.conProviders.isEmpty()) {
12731            for (int i=0; i<app.conProviders.size(); i++) {
12732                ContentProviderConnection conn = app.conProviders.get(i);
12733                conn.provider.connections.remove(conn);
12734            }
12735            app.conProviders.clear();
12736        }
12737
12738        // At this point there may be remaining entries in mLaunchingProviders
12739        // where we were the only one waiting, so they are no longer of use.
12740        // Look for these and clean up if found.
12741        // XXX Commented out for now.  Trying to figure out a way to reproduce
12742        // the actual situation to identify what is actually going on.
12743        if (false) {
12744            for (int i=0; i<mLaunchingProviders.size(); i++) {
12745                ContentProviderRecord cpr = (ContentProviderRecord)
12746                        mLaunchingProviders.get(i);
12747                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12748                    synchronized (cpr) {
12749                        cpr.launchingApp = null;
12750                        cpr.notifyAll();
12751                    }
12752                }
12753            }
12754        }
12755
12756        skipCurrentReceiverLocked(app);
12757
12758        // Unregister any receivers.
12759        for (int i=app.receivers.size()-1; i>=0; i--) {
12760            removeReceiverLocked(app.receivers.valueAt(i));
12761        }
12762        app.receivers.clear();
12763
12764        // If the app is undergoing backup, tell the backup manager about it
12765        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12766            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12767                    + mBackupTarget.appInfo + " died during backup");
12768            try {
12769                IBackupManager bm = IBackupManager.Stub.asInterface(
12770                        ServiceManager.getService(Context.BACKUP_SERVICE));
12771                bm.agentDisconnected(app.info.packageName);
12772            } catch (RemoteException e) {
12773                // can't happen; backup manager is local
12774            }
12775        }
12776
12777        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12778            ProcessChangeItem item = mPendingProcessChanges.get(i);
12779            if (item.pid == app.pid) {
12780                mPendingProcessChanges.remove(i);
12781                mAvailProcessChanges.add(item);
12782            }
12783        }
12784        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12785
12786        // If the caller is restarting this app, then leave it in its
12787        // current lists and let the caller take care of it.
12788        if (restarting) {
12789            return;
12790        }
12791
12792        if (!app.persistent || app.isolated) {
12793            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12794                    "Removing non-persistent process during cleanup: " + app);
12795            mProcessNames.remove(app.processName, app.uid);
12796            mIsolatedProcesses.remove(app.uid);
12797            if (mHeavyWeightProcess == app) {
12798                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12799                        mHeavyWeightProcess.userId, 0));
12800                mHeavyWeightProcess = null;
12801            }
12802        } else if (!app.removed) {
12803            // This app is persistent, so we need to keep its record around.
12804            // If it is not already on the pending app list, add it there
12805            // and start a new process for it.
12806            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12807                mPersistentStartingProcesses.add(app);
12808                restart = true;
12809            }
12810        }
12811        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12812                "Clean-up removing on hold: " + app);
12813        mProcessesOnHold.remove(app);
12814
12815        if (app == mHomeProcess) {
12816            mHomeProcess = null;
12817        }
12818        if (app == mPreviousProcess) {
12819            mPreviousProcess = null;
12820        }
12821
12822        if (restart && !app.isolated) {
12823            // We have components that still need to be running in the
12824            // process, so re-launch it.
12825            mProcessNames.put(app.processName, app.uid, app);
12826            startProcessLocked(app, "restart", app.processName);
12827        } else if (app.pid > 0 && app.pid != MY_PID) {
12828            // Goodbye!
12829            boolean removed;
12830            synchronized (mPidsSelfLocked) {
12831                mPidsSelfLocked.remove(app.pid);
12832                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12833            }
12834            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12835                    app.processName, app.info.uid);
12836            if (app.isolated) {
12837                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12838            }
12839            app.setPid(0);
12840        }
12841    }
12842
12843    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12844        // Look through the content providers we are waiting to have launched,
12845        // and if any run in this process then either schedule a restart of
12846        // the process or kill the client waiting for it if this process has
12847        // gone bad.
12848        int NL = mLaunchingProviders.size();
12849        boolean restart = false;
12850        for (int i=0; i<NL; i++) {
12851            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12852            if (cpr.launchingApp == app) {
12853                if (!alwaysBad && !app.bad) {
12854                    restart = true;
12855                } else {
12856                    removeDyingProviderLocked(app, cpr, true);
12857                    // cpr should have been removed from mLaunchingProviders
12858                    NL = mLaunchingProviders.size();
12859                    i--;
12860                }
12861            }
12862        }
12863        return restart;
12864    }
12865
12866    // =========================================================
12867    // SERVICES
12868    // =========================================================
12869
12870    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12871            int flags) {
12872        enforceNotIsolatedCaller("getServices");
12873        synchronized (this) {
12874            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12875        }
12876    }
12877
12878    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12879        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12880        synchronized (this) {
12881            return mServices.getRunningServiceControlPanelLocked(name);
12882        }
12883    }
12884
12885    public ComponentName startService(IApplicationThread caller, Intent service,
12886            String resolvedType, int userId) {
12887        enforceNotIsolatedCaller("startService");
12888        // Refuse possible leaked file descriptors
12889        if (service != null && service.hasFileDescriptors() == true) {
12890            throw new IllegalArgumentException("File descriptors passed in Intent");
12891        }
12892
12893        if (DEBUG_SERVICE)
12894            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12895        synchronized(this) {
12896            final int callingPid = Binder.getCallingPid();
12897            final int callingUid = Binder.getCallingUid();
12898            final long origId = Binder.clearCallingIdentity();
12899            ComponentName res = mServices.startServiceLocked(caller, service,
12900                    resolvedType, callingPid, callingUid, userId);
12901            Binder.restoreCallingIdentity(origId);
12902            return res;
12903        }
12904    }
12905
12906    ComponentName startServiceInPackage(int uid,
12907            Intent service, String resolvedType, int userId) {
12908        synchronized(this) {
12909            if (DEBUG_SERVICE)
12910                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12911            final long origId = Binder.clearCallingIdentity();
12912            ComponentName res = mServices.startServiceLocked(null, service,
12913                    resolvedType, -1, uid, userId);
12914            Binder.restoreCallingIdentity(origId);
12915            return res;
12916        }
12917    }
12918
12919    public int stopService(IApplicationThread caller, Intent service,
12920            String resolvedType, int userId) {
12921        enforceNotIsolatedCaller("stopService");
12922        // Refuse possible leaked file descriptors
12923        if (service != null && service.hasFileDescriptors() == true) {
12924            throw new IllegalArgumentException("File descriptors passed in Intent");
12925        }
12926
12927        synchronized(this) {
12928            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12929        }
12930    }
12931
12932    public IBinder peekService(Intent service, String resolvedType) {
12933        enforceNotIsolatedCaller("peekService");
12934        // Refuse possible leaked file descriptors
12935        if (service != null && service.hasFileDescriptors() == true) {
12936            throw new IllegalArgumentException("File descriptors passed in Intent");
12937        }
12938        synchronized(this) {
12939            return mServices.peekServiceLocked(service, resolvedType);
12940        }
12941    }
12942
12943    public boolean stopServiceToken(ComponentName className, IBinder token,
12944            int startId) {
12945        synchronized(this) {
12946            return mServices.stopServiceTokenLocked(className, token, startId);
12947        }
12948    }
12949
12950    public void setServiceForeground(ComponentName className, IBinder token,
12951            int id, Notification notification, boolean removeNotification) {
12952        synchronized(this) {
12953            mServices.setServiceForegroundLocked(className, token, id, notification,
12954                    removeNotification);
12955        }
12956    }
12957
12958    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12959            boolean requireFull, String name, String callerPackage) {
12960        final int callingUserId = UserHandle.getUserId(callingUid);
12961        if (callingUserId != userId) {
12962            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12963                if ((requireFull || checkComponentPermission(
12964                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12965                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12966                        && checkComponentPermission(
12967                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12968                                callingPid, callingUid, -1, true)
12969                                != PackageManager.PERMISSION_GRANTED) {
12970                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12971                        // In this case, they would like to just execute as their
12972                        // owner user instead of failing.
12973                        userId = callingUserId;
12974                    } else {
12975                        StringBuilder builder = new StringBuilder(128);
12976                        builder.append("Permission Denial: ");
12977                        builder.append(name);
12978                        if (callerPackage != null) {
12979                            builder.append(" from ");
12980                            builder.append(callerPackage);
12981                        }
12982                        builder.append(" asks to run as user ");
12983                        builder.append(userId);
12984                        builder.append(" but is calling from user ");
12985                        builder.append(UserHandle.getUserId(callingUid));
12986                        builder.append("; this requires ");
12987                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12988                        if (!requireFull) {
12989                            builder.append(" or ");
12990                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12991                        }
12992                        String msg = builder.toString();
12993                        Slog.w(TAG, msg);
12994                        throw new SecurityException(msg);
12995                    }
12996                }
12997            }
12998            if (userId == UserHandle.USER_CURRENT
12999                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13000                // Note that we may be accessing this outside of a lock...
13001                // shouldn't be a big deal, if this is being called outside
13002                // of a locked context there is intrinsically a race with
13003                // the value the caller will receive and someone else changing it.
13004                userId = mCurrentUserId;
13005            }
13006            if (!allowAll && userId < 0) {
13007                throw new IllegalArgumentException(
13008                        "Call does not support special user #" + userId);
13009            }
13010        }
13011        return userId;
13012    }
13013
13014    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13015            String className, int flags) {
13016        boolean result = false;
13017        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13018            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13019                if (ActivityManager.checkUidPermission(
13020                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13021                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13022                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13023                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13024                            + " requests FLAG_SINGLE_USER, but app does not hold "
13025                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13026                    Slog.w(TAG, msg);
13027                    throw new SecurityException(msg);
13028                }
13029                result = true;
13030            }
13031        } else if (componentProcessName == aInfo.packageName) {
13032            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13033        } else if ("system".equals(componentProcessName)) {
13034            result = true;
13035        }
13036        if (DEBUG_MU) {
13037            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13038                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13039        }
13040        return result;
13041    }
13042
13043    public int bindService(IApplicationThread caller, IBinder token,
13044            Intent service, String resolvedType,
13045            IServiceConnection connection, int flags, int userId) {
13046        enforceNotIsolatedCaller("bindService");
13047        // Refuse possible leaked file descriptors
13048        if (service != null && service.hasFileDescriptors() == true) {
13049            throw new IllegalArgumentException("File descriptors passed in Intent");
13050        }
13051
13052        synchronized(this) {
13053            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13054                    connection, flags, userId);
13055        }
13056    }
13057
13058    public boolean unbindService(IServiceConnection connection) {
13059        synchronized (this) {
13060            return mServices.unbindServiceLocked(connection);
13061        }
13062    }
13063
13064    public void publishService(IBinder token, Intent intent, IBinder service) {
13065        // Refuse possible leaked file descriptors
13066        if (intent != null && intent.hasFileDescriptors() == true) {
13067            throw new IllegalArgumentException("File descriptors passed in Intent");
13068        }
13069
13070        synchronized(this) {
13071            if (!(token instanceof ServiceRecord)) {
13072                throw new IllegalArgumentException("Invalid service token");
13073            }
13074            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13075        }
13076    }
13077
13078    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13079        // Refuse possible leaked file descriptors
13080        if (intent != null && intent.hasFileDescriptors() == true) {
13081            throw new IllegalArgumentException("File descriptors passed in Intent");
13082        }
13083
13084        synchronized(this) {
13085            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13086        }
13087    }
13088
13089    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13090        synchronized(this) {
13091            if (!(token instanceof ServiceRecord)) {
13092                throw new IllegalArgumentException("Invalid service token");
13093            }
13094            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13095        }
13096    }
13097
13098    // =========================================================
13099    // BACKUP AND RESTORE
13100    // =========================================================
13101
13102    // Cause the target app to be launched if necessary and its backup agent
13103    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13104    // activity manager to announce its creation.
13105    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13106        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13107        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13108
13109        synchronized(this) {
13110            // !!! TODO: currently no check here that we're already bound
13111            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13112            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13113            synchronized (stats) {
13114                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13115            }
13116
13117            // Backup agent is now in use, its package can't be stopped.
13118            try {
13119                AppGlobals.getPackageManager().setPackageStoppedState(
13120                        app.packageName, false, UserHandle.getUserId(app.uid));
13121            } catch (RemoteException e) {
13122            } catch (IllegalArgumentException e) {
13123                Slog.w(TAG, "Failed trying to unstop package "
13124                        + app.packageName + ": " + e);
13125            }
13126
13127            BackupRecord r = new BackupRecord(ss, app, backupMode);
13128            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13129                    ? new ComponentName(app.packageName, app.backupAgentName)
13130                    : new ComponentName("android", "FullBackupAgent");
13131            // startProcessLocked() returns existing proc's record if it's already running
13132            ProcessRecord proc = startProcessLocked(app.processName, app,
13133                    false, 0, "backup", hostingName, false, false, false);
13134            if (proc == null) {
13135                Slog.e(TAG, "Unable to start backup agent process " + r);
13136                return false;
13137            }
13138
13139            r.app = proc;
13140            mBackupTarget = r;
13141            mBackupAppName = app.packageName;
13142
13143            // Try not to kill the process during backup
13144            updateOomAdjLocked(proc);
13145
13146            // If the process is already attached, schedule the creation of the backup agent now.
13147            // If it is not yet live, this will be done when it attaches to the framework.
13148            if (proc.thread != null) {
13149                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13150                try {
13151                    proc.thread.scheduleCreateBackupAgent(app,
13152                            compatibilityInfoForPackageLocked(app), backupMode);
13153                } catch (RemoteException e) {
13154                    // Will time out on the backup manager side
13155                }
13156            } else {
13157                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13158            }
13159            // Invariants: at this point, the target app process exists and the application
13160            // is either already running or in the process of coming up.  mBackupTarget and
13161            // mBackupAppName describe the app, so that when it binds back to the AM we
13162            // know that it's scheduled for a backup-agent operation.
13163        }
13164
13165        return true;
13166    }
13167
13168    @Override
13169    public void clearPendingBackup() {
13170        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13171        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13172
13173        synchronized (this) {
13174            mBackupTarget = null;
13175            mBackupAppName = null;
13176        }
13177    }
13178
13179    // A backup agent has just come up
13180    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13181        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13182                + " = " + agent);
13183
13184        synchronized(this) {
13185            if (!agentPackageName.equals(mBackupAppName)) {
13186                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13187                return;
13188            }
13189        }
13190
13191        long oldIdent = Binder.clearCallingIdentity();
13192        try {
13193            IBackupManager bm = IBackupManager.Stub.asInterface(
13194                    ServiceManager.getService(Context.BACKUP_SERVICE));
13195            bm.agentConnected(agentPackageName, agent);
13196        } catch (RemoteException e) {
13197            // can't happen; the backup manager service is local
13198        } catch (Exception e) {
13199            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13200            e.printStackTrace();
13201        } finally {
13202            Binder.restoreCallingIdentity(oldIdent);
13203        }
13204    }
13205
13206    // done with this agent
13207    public void unbindBackupAgent(ApplicationInfo appInfo) {
13208        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13209        if (appInfo == null) {
13210            Slog.w(TAG, "unbind backup agent for null app");
13211            return;
13212        }
13213
13214        synchronized(this) {
13215            try {
13216                if (mBackupAppName == null) {
13217                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13218                    return;
13219                }
13220
13221                if (!mBackupAppName.equals(appInfo.packageName)) {
13222                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13223                    return;
13224                }
13225
13226                // Not backing this app up any more; reset its OOM adjustment
13227                final ProcessRecord proc = mBackupTarget.app;
13228                updateOomAdjLocked(proc);
13229
13230                // If the app crashed during backup, 'thread' will be null here
13231                if (proc.thread != null) {
13232                    try {
13233                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13234                                compatibilityInfoForPackageLocked(appInfo));
13235                    } catch (Exception e) {
13236                        Slog.e(TAG, "Exception when unbinding backup agent:");
13237                        e.printStackTrace();
13238                    }
13239                }
13240            } finally {
13241                mBackupTarget = null;
13242                mBackupAppName = null;
13243            }
13244        }
13245    }
13246    // =========================================================
13247    // BROADCASTS
13248    // =========================================================
13249
13250    private final List getStickiesLocked(String action, IntentFilter filter,
13251            List cur, int userId) {
13252        final ContentResolver resolver = mContext.getContentResolver();
13253        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13254        if (stickies == null) {
13255            return cur;
13256        }
13257        final ArrayList<Intent> list = stickies.get(action);
13258        if (list == null) {
13259            return cur;
13260        }
13261        int N = list.size();
13262        for (int i=0; i<N; i++) {
13263            Intent intent = list.get(i);
13264            if (filter.match(resolver, intent, true, TAG) >= 0) {
13265                if (cur == null) {
13266                    cur = new ArrayList<Intent>();
13267                }
13268                cur.add(intent);
13269            }
13270        }
13271        return cur;
13272    }
13273
13274    boolean isPendingBroadcastProcessLocked(int pid) {
13275        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13276                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13277    }
13278
13279    void skipPendingBroadcastLocked(int pid) {
13280            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13281            for (BroadcastQueue queue : mBroadcastQueues) {
13282                queue.skipPendingBroadcastLocked(pid);
13283            }
13284    }
13285
13286    // The app just attached; send any pending broadcasts that it should receive
13287    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13288        boolean didSomething = false;
13289        for (BroadcastQueue queue : mBroadcastQueues) {
13290            didSomething |= queue.sendPendingBroadcastsLocked(app);
13291        }
13292        return didSomething;
13293    }
13294
13295    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13296            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13297        enforceNotIsolatedCaller("registerReceiver");
13298        int callingUid;
13299        int callingPid;
13300        synchronized(this) {
13301            ProcessRecord callerApp = null;
13302            if (caller != null) {
13303                callerApp = getRecordForAppLocked(caller);
13304                if (callerApp == null) {
13305                    throw new SecurityException(
13306                            "Unable to find app for caller " + caller
13307                            + " (pid=" + Binder.getCallingPid()
13308                            + ") when registering receiver " + receiver);
13309                }
13310                if (callerApp.info.uid != Process.SYSTEM_UID &&
13311                        !callerApp.pkgList.containsKey(callerPackage) &&
13312                        !"android".equals(callerPackage)) {
13313                    throw new SecurityException("Given caller package " + callerPackage
13314                            + " is not running in process " + callerApp);
13315                }
13316                callingUid = callerApp.info.uid;
13317                callingPid = callerApp.pid;
13318            } else {
13319                callerPackage = null;
13320                callingUid = Binder.getCallingUid();
13321                callingPid = Binder.getCallingPid();
13322            }
13323
13324            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13325                    true, true, "registerReceiver", callerPackage);
13326
13327            List allSticky = null;
13328
13329            // Look for any matching sticky broadcasts...
13330            Iterator actions = filter.actionsIterator();
13331            if (actions != null) {
13332                while (actions.hasNext()) {
13333                    String action = (String)actions.next();
13334                    allSticky = getStickiesLocked(action, filter, allSticky,
13335                            UserHandle.USER_ALL);
13336                    allSticky = getStickiesLocked(action, filter, allSticky,
13337                            UserHandle.getUserId(callingUid));
13338                }
13339            } else {
13340                allSticky = getStickiesLocked(null, filter, allSticky,
13341                        UserHandle.USER_ALL);
13342                allSticky = getStickiesLocked(null, filter, allSticky,
13343                        UserHandle.getUserId(callingUid));
13344            }
13345
13346            // The first sticky in the list is returned directly back to
13347            // the client.
13348            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13349
13350            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13351                    + ": " + sticky);
13352
13353            if (receiver == null) {
13354                return sticky;
13355            }
13356
13357            ReceiverList rl
13358                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13359            if (rl == null) {
13360                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13361                        userId, receiver);
13362                if (rl.app != null) {
13363                    rl.app.receivers.add(rl);
13364                } else {
13365                    try {
13366                        receiver.asBinder().linkToDeath(rl, 0);
13367                    } catch (RemoteException e) {
13368                        return sticky;
13369                    }
13370                    rl.linkedToDeath = true;
13371                }
13372                mRegisteredReceivers.put(receiver.asBinder(), rl);
13373            } else if (rl.uid != callingUid) {
13374                throw new IllegalArgumentException(
13375                        "Receiver requested to register for uid " + callingUid
13376                        + " was previously registered for uid " + rl.uid);
13377            } else if (rl.pid != callingPid) {
13378                throw new IllegalArgumentException(
13379                        "Receiver requested to register for pid " + callingPid
13380                        + " was previously registered for pid " + rl.pid);
13381            } else if (rl.userId != userId) {
13382                throw new IllegalArgumentException(
13383                        "Receiver requested to register for user " + userId
13384                        + " was previously registered for user " + rl.userId);
13385            }
13386            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13387                    permission, callingUid, userId);
13388            rl.add(bf);
13389            if (!bf.debugCheck()) {
13390                Slog.w(TAG, "==> For Dynamic broadast");
13391            }
13392            mReceiverResolver.addFilter(bf);
13393
13394            // Enqueue broadcasts for all existing stickies that match
13395            // this filter.
13396            if (allSticky != null) {
13397                ArrayList receivers = new ArrayList();
13398                receivers.add(bf);
13399
13400                int N = allSticky.size();
13401                for (int i=0; i<N; i++) {
13402                    Intent intent = (Intent)allSticky.get(i);
13403                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13404                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13405                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13406                            null, null, false, true, true, -1);
13407                    queue.enqueueParallelBroadcastLocked(r);
13408                    queue.scheduleBroadcastsLocked();
13409                }
13410            }
13411
13412            return sticky;
13413        }
13414    }
13415
13416    public void unregisterReceiver(IIntentReceiver receiver) {
13417        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13418
13419        final long origId = Binder.clearCallingIdentity();
13420        try {
13421            boolean doTrim = false;
13422
13423            synchronized(this) {
13424                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13425                if (rl != null) {
13426                    if (rl.curBroadcast != null) {
13427                        BroadcastRecord r = rl.curBroadcast;
13428                        final boolean doNext = finishReceiverLocked(
13429                                receiver.asBinder(), r.resultCode, r.resultData,
13430                                r.resultExtras, r.resultAbort);
13431                        if (doNext) {
13432                            doTrim = true;
13433                            r.queue.processNextBroadcast(false);
13434                        }
13435                    }
13436
13437                    if (rl.app != null) {
13438                        rl.app.receivers.remove(rl);
13439                    }
13440                    removeReceiverLocked(rl);
13441                    if (rl.linkedToDeath) {
13442                        rl.linkedToDeath = false;
13443                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13444                    }
13445                }
13446            }
13447
13448            // If we actually concluded any broadcasts, we might now be able
13449            // to trim the recipients' apps from our working set
13450            if (doTrim) {
13451                trimApplications();
13452                return;
13453            }
13454
13455        } finally {
13456            Binder.restoreCallingIdentity(origId);
13457        }
13458    }
13459
13460    void removeReceiverLocked(ReceiverList rl) {
13461        mRegisteredReceivers.remove(rl.receiver.asBinder());
13462        int N = rl.size();
13463        for (int i=0; i<N; i++) {
13464            mReceiverResolver.removeFilter(rl.get(i));
13465        }
13466    }
13467
13468    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13469        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13470            ProcessRecord r = mLruProcesses.get(i);
13471            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13472                try {
13473                    r.thread.dispatchPackageBroadcast(cmd, packages);
13474                } catch (RemoteException ex) {
13475                }
13476            }
13477        }
13478    }
13479
13480    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13481            int[] users) {
13482        List<ResolveInfo> receivers = null;
13483        try {
13484            HashSet<ComponentName> singleUserReceivers = null;
13485            boolean scannedFirstReceivers = false;
13486            for (int user : users) {
13487                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13488                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13489                if (user != 0 && newReceivers != null) {
13490                    // If this is not the primary user, we need to check for
13491                    // any receivers that should be filtered out.
13492                    for (int i=0; i<newReceivers.size(); i++) {
13493                        ResolveInfo ri = newReceivers.get(i);
13494                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13495                            newReceivers.remove(i);
13496                            i--;
13497                        }
13498                    }
13499                }
13500                if (newReceivers != null && newReceivers.size() == 0) {
13501                    newReceivers = null;
13502                }
13503                if (receivers == null) {
13504                    receivers = newReceivers;
13505                } else if (newReceivers != null) {
13506                    // We need to concatenate the additional receivers
13507                    // found with what we have do far.  This would be easy,
13508                    // but we also need to de-dup any receivers that are
13509                    // singleUser.
13510                    if (!scannedFirstReceivers) {
13511                        // Collect any single user receivers we had already retrieved.
13512                        scannedFirstReceivers = true;
13513                        for (int i=0; i<receivers.size(); i++) {
13514                            ResolveInfo ri = receivers.get(i);
13515                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13516                                ComponentName cn = new ComponentName(
13517                                        ri.activityInfo.packageName, ri.activityInfo.name);
13518                                if (singleUserReceivers == null) {
13519                                    singleUserReceivers = new HashSet<ComponentName>();
13520                                }
13521                                singleUserReceivers.add(cn);
13522                            }
13523                        }
13524                    }
13525                    // Add the new results to the existing results, tracking
13526                    // and de-dupping single user receivers.
13527                    for (int i=0; i<newReceivers.size(); i++) {
13528                        ResolveInfo ri = newReceivers.get(i);
13529                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13530                            ComponentName cn = new ComponentName(
13531                                    ri.activityInfo.packageName, ri.activityInfo.name);
13532                            if (singleUserReceivers == null) {
13533                                singleUserReceivers = new HashSet<ComponentName>();
13534                            }
13535                            if (!singleUserReceivers.contains(cn)) {
13536                                singleUserReceivers.add(cn);
13537                                receivers.add(ri);
13538                            }
13539                        } else {
13540                            receivers.add(ri);
13541                        }
13542                    }
13543                }
13544            }
13545        } catch (RemoteException ex) {
13546            // pm is in same process, this will never happen.
13547        }
13548        return receivers;
13549    }
13550
13551    private final int broadcastIntentLocked(ProcessRecord callerApp,
13552            String callerPackage, Intent intent, String resolvedType,
13553            IIntentReceiver resultTo, int resultCode, String resultData,
13554            Bundle map, String requiredPermission, int appOp,
13555            boolean ordered, boolean sticky, int callingPid, int callingUid,
13556            int userId) {
13557        intent = new Intent(intent);
13558
13559        // By default broadcasts do not go to stopped apps.
13560        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13561
13562        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13563            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13564            + " ordered=" + ordered + " userid=" + userId);
13565        if ((resultTo != null) && !ordered) {
13566            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13567        }
13568
13569        userId = handleIncomingUser(callingPid, callingUid, userId,
13570                true, false, "broadcast", callerPackage);
13571
13572        // Make sure that the user who is receiving this broadcast is started.
13573        // If not, we will just skip it.
13574        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13575            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13576                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13577                Slog.w(TAG, "Skipping broadcast of " + intent
13578                        + ": user " + userId + " is stopped");
13579                return ActivityManager.BROADCAST_SUCCESS;
13580            }
13581        }
13582
13583        /*
13584         * Prevent non-system code (defined here to be non-persistent
13585         * processes) from sending protected broadcasts.
13586         */
13587        int callingAppId = UserHandle.getAppId(callingUid);
13588        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13589            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13590            callingUid == 0) {
13591            // Always okay.
13592        } else if (callerApp == null || !callerApp.persistent) {
13593            try {
13594                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13595                        intent.getAction())) {
13596                    String msg = "Permission Denial: not allowed to send broadcast "
13597                            + intent.getAction() + " from pid="
13598                            + callingPid + ", uid=" + callingUid;
13599                    Slog.w(TAG, msg);
13600                    throw new SecurityException(msg);
13601                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13602                    // Special case for compatibility: we don't want apps to send this,
13603                    // but historically it has not been protected and apps may be using it
13604                    // to poke their own app widget.  So, instead of making it protected,
13605                    // just limit it to the caller.
13606                    if (callerApp == null) {
13607                        String msg = "Permission Denial: not allowed to send broadcast "
13608                                + intent.getAction() + " from unknown caller.";
13609                        Slog.w(TAG, msg);
13610                        throw new SecurityException(msg);
13611                    } else if (intent.getComponent() != null) {
13612                        // They are good enough to send to an explicit component...  verify
13613                        // it is being sent to the calling app.
13614                        if (!intent.getComponent().getPackageName().equals(
13615                                callerApp.info.packageName)) {
13616                            String msg = "Permission Denial: not allowed to send broadcast "
13617                                    + intent.getAction() + " to "
13618                                    + intent.getComponent().getPackageName() + " from "
13619                                    + callerApp.info.packageName;
13620                            Slog.w(TAG, msg);
13621                            throw new SecurityException(msg);
13622                        }
13623                    } else {
13624                        // Limit broadcast to their own package.
13625                        intent.setPackage(callerApp.info.packageName);
13626                    }
13627                }
13628            } catch (RemoteException e) {
13629                Slog.w(TAG, "Remote exception", e);
13630                return ActivityManager.BROADCAST_SUCCESS;
13631            }
13632        }
13633
13634        // Handle special intents: if this broadcast is from the package
13635        // manager about a package being removed, we need to remove all of
13636        // its activities from the history stack.
13637        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13638                intent.getAction());
13639        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13640                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13641                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13642                || uidRemoved) {
13643            if (checkComponentPermission(
13644                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13645                    callingPid, callingUid, -1, true)
13646                    == PackageManager.PERMISSION_GRANTED) {
13647                if (uidRemoved) {
13648                    final Bundle intentExtras = intent.getExtras();
13649                    final int uid = intentExtras != null
13650                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13651                    if (uid >= 0) {
13652                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13653                        synchronized (bs) {
13654                            bs.removeUidStatsLocked(uid);
13655                        }
13656                        mAppOpsService.uidRemoved(uid);
13657                    }
13658                } else {
13659                    // If resources are unavailable just force stop all
13660                    // those packages and flush the attribute cache as well.
13661                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13662                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13663                        if (list != null && (list.length > 0)) {
13664                            for (String pkg : list) {
13665                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13666                                        "storage unmount");
13667                            }
13668                            sendPackageBroadcastLocked(
13669                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13670                        }
13671                    } else {
13672                        Uri data = intent.getData();
13673                        String ssp;
13674                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13675                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13676                                    intent.getAction());
13677                            boolean fullUninstall = removed &&
13678                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13679                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13680                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13681                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13682                                        false, fullUninstall, userId,
13683                                        removed ? "pkg removed" : "pkg changed");
13684                            }
13685                            if (removed) {
13686                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13687                                        new String[] {ssp}, userId);
13688                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13689                                    mAppOpsService.packageRemoved(
13690                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13691
13692                                    // Remove all permissions granted from/to this package
13693                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13694                                }
13695                            }
13696                        }
13697                    }
13698                }
13699            } else {
13700                String msg = "Permission Denial: " + intent.getAction()
13701                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13702                        + ", uid=" + callingUid + ")"
13703                        + " requires "
13704                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13705                Slog.w(TAG, msg);
13706                throw new SecurityException(msg);
13707            }
13708
13709        // Special case for adding a package: by default turn on compatibility
13710        // mode.
13711        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13712            Uri data = intent.getData();
13713            String ssp;
13714            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13715                mCompatModePackages.handlePackageAddedLocked(ssp,
13716                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13717            }
13718        }
13719
13720        /*
13721         * If this is the time zone changed action, queue up a message that will reset the timezone
13722         * of all currently running processes. This message will get queued up before the broadcast
13723         * happens.
13724         */
13725        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13726            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13727        }
13728
13729        /*
13730         * If the user set the time, let all running processes know.
13731         */
13732        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13733            final int is24Hour = intent.getBooleanExtra(
13734                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13735            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13736        }
13737
13738        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13739            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13740        }
13741
13742        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13743            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13744            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13745        }
13746
13747        // Add to the sticky list if requested.
13748        if (sticky) {
13749            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13750                    callingPid, callingUid)
13751                    != PackageManager.PERMISSION_GRANTED) {
13752                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13753                        + callingPid + ", uid=" + callingUid
13754                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13755                Slog.w(TAG, msg);
13756                throw new SecurityException(msg);
13757            }
13758            if (requiredPermission != null) {
13759                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13760                        + " and enforce permission " + requiredPermission);
13761                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13762            }
13763            if (intent.getComponent() != null) {
13764                throw new SecurityException(
13765                        "Sticky broadcasts can't target a specific component");
13766            }
13767            // We use userId directly here, since the "all" target is maintained
13768            // as a separate set of sticky broadcasts.
13769            if (userId != UserHandle.USER_ALL) {
13770                // But first, if this is not a broadcast to all users, then
13771                // make sure it doesn't conflict with an existing broadcast to
13772                // all users.
13773                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13774                        UserHandle.USER_ALL);
13775                if (stickies != null) {
13776                    ArrayList<Intent> list = stickies.get(intent.getAction());
13777                    if (list != null) {
13778                        int N = list.size();
13779                        int i;
13780                        for (i=0; i<N; i++) {
13781                            if (intent.filterEquals(list.get(i))) {
13782                                throw new IllegalArgumentException(
13783                                        "Sticky broadcast " + intent + " for user "
13784                                        + userId + " conflicts with existing global broadcast");
13785                            }
13786                        }
13787                    }
13788                }
13789            }
13790            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13791            if (stickies == null) {
13792                stickies = new ArrayMap<String, ArrayList<Intent>>();
13793                mStickyBroadcasts.put(userId, stickies);
13794            }
13795            ArrayList<Intent> list = stickies.get(intent.getAction());
13796            if (list == null) {
13797                list = new ArrayList<Intent>();
13798                stickies.put(intent.getAction(), list);
13799            }
13800            int N = list.size();
13801            int i;
13802            for (i=0; i<N; i++) {
13803                if (intent.filterEquals(list.get(i))) {
13804                    // This sticky already exists, replace it.
13805                    list.set(i, new Intent(intent));
13806                    break;
13807                }
13808            }
13809            if (i >= N) {
13810                list.add(new Intent(intent));
13811            }
13812        }
13813
13814        int[] users;
13815        if (userId == UserHandle.USER_ALL) {
13816            // Caller wants broadcast to go to all started users.
13817            users = mStartedUserArray;
13818        } else {
13819            // Caller wants broadcast to go to one specific user.
13820            users = new int[] {userId};
13821        }
13822
13823        // Figure out who all will receive this broadcast.
13824        List receivers = null;
13825        List<BroadcastFilter> registeredReceivers = null;
13826        // Need to resolve the intent to interested receivers...
13827        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13828                 == 0) {
13829            receivers = collectReceiverComponents(intent, resolvedType, users);
13830        }
13831        if (intent.getComponent() == null) {
13832            registeredReceivers = mReceiverResolver.queryIntent(intent,
13833                    resolvedType, false, userId);
13834        }
13835
13836        final boolean replacePending =
13837                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13838
13839        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13840                + " replacePending=" + replacePending);
13841
13842        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13843        if (!ordered && NR > 0) {
13844            // If we are not serializing this broadcast, then send the
13845            // registered receivers separately so they don't wait for the
13846            // components to be launched.
13847            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13848            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13849                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13850                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13851                    ordered, sticky, false, userId);
13852            if (DEBUG_BROADCAST) Slog.v(
13853                    TAG, "Enqueueing parallel broadcast " + r);
13854            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13855            if (!replaced) {
13856                queue.enqueueParallelBroadcastLocked(r);
13857                queue.scheduleBroadcastsLocked();
13858            }
13859            registeredReceivers = null;
13860            NR = 0;
13861        }
13862
13863        // Merge into one list.
13864        int ir = 0;
13865        if (receivers != null) {
13866            // A special case for PACKAGE_ADDED: do not allow the package
13867            // being added to see this broadcast.  This prevents them from
13868            // using this as a back door to get run as soon as they are
13869            // installed.  Maybe in the future we want to have a special install
13870            // broadcast or such for apps, but we'd like to deliberately make
13871            // this decision.
13872            String skipPackages[] = null;
13873            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13874                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13875                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13876                Uri data = intent.getData();
13877                if (data != null) {
13878                    String pkgName = data.getSchemeSpecificPart();
13879                    if (pkgName != null) {
13880                        skipPackages = new String[] { pkgName };
13881                    }
13882                }
13883            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13884                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13885            }
13886            if (skipPackages != null && (skipPackages.length > 0)) {
13887                for (String skipPackage : skipPackages) {
13888                    if (skipPackage != null) {
13889                        int NT = receivers.size();
13890                        for (int it=0; it<NT; it++) {
13891                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13892                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13893                                receivers.remove(it);
13894                                it--;
13895                                NT--;
13896                            }
13897                        }
13898                    }
13899                }
13900            }
13901
13902            int NT = receivers != null ? receivers.size() : 0;
13903            int it = 0;
13904            ResolveInfo curt = null;
13905            BroadcastFilter curr = null;
13906            while (it < NT && ir < NR) {
13907                if (curt == null) {
13908                    curt = (ResolveInfo)receivers.get(it);
13909                }
13910                if (curr == null) {
13911                    curr = registeredReceivers.get(ir);
13912                }
13913                if (curr.getPriority() >= curt.priority) {
13914                    // Insert this broadcast record into the final list.
13915                    receivers.add(it, curr);
13916                    ir++;
13917                    curr = null;
13918                    it++;
13919                    NT++;
13920                } else {
13921                    // Skip to the next ResolveInfo in the final list.
13922                    it++;
13923                    curt = null;
13924                }
13925            }
13926        }
13927        while (ir < NR) {
13928            if (receivers == null) {
13929                receivers = new ArrayList();
13930            }
13931            receivers.add(registeredReceivers.get(ir));
13932            ir++;
13933        }
13934
13935        if ((receivers != null && receivers.size() > 0)
13936                || resultTo != null) {
13937            BroadcastQueue queue = broadcastQueueForIntent(intent);
13938            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13939                    callerPackage, callingPid, callingUid, resolvedType,
13940                    requiredPermission, appOp, receivers, resultTo, resultCode,
13941                    resultData, map, ordered, sticky, false, userId);
13942            if (DEBUG_BROADCAST) Slog.v(
13943                    TAG, "Enqueueing ordered broadcast " + r
13944                    + ": prev had " + queue.mOrderedBroadcasts.size());
13945            if (DEBUG_BROADCAST) {
13946                int seq = r.intent.getIntExtra("seq", -1);
13947                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13948            }
13949            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13950            if (!replaced) {
13951                queue.enqueueOrderedBroadcastLocked(r);
13952                queue.scheduleBroadcastsLocked();
13953            }
13954        }
13955
13956        return ActivityManager.BROADCAST_SUCCESS;
13957    }
13958
13959    final Intent verifyBroadcastLocked(Intent intent) {
13960        // Refuse possible leaked file descriptors
13961        if (intent != null && intent.hasFileDescriptors() == true) {
13962            throw new IllegalArgumentException("File descriptors passed in Intent");
13963        }
13964
13965        int flags = intent.getFlags();
13966
13967        if (!mProcessesReady) {
13968            // if the caller really truly claims to know what they're doing, go
13969            // ahead and allow the broadcast without launching any receivers
13970            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13971                intent = new Intent(intent);
13972                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13973            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13974                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13975                        + " before boot completion");
13976                throw new IllegalStateException("Cannot broadcast before boot completed");
13977            }
13978        }
13979
13980        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13981            throw new IllegalArgumentException(
13982                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13983        }
13984
13985        return intent;
13986    }
13987
13988    public final int broadcastIntent(IApplicationThread caller,
13989            Intent intent, String resolvedType, IIntentReceiver resultTo,
13990            int resultCode, String resultData, Bundle map,
13991            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13992        enforceNotIsolatedCaller("broadcastIntent");
13993        synchronized(this) {
13994            intent = verifyBroadcastLocked(intent);
13995
13996            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13997            final int callingPid = Binder.getCallingPid();
13998            final int callingUid = Binder.getCallingUid();
13999            final long origId = Binder.clearCallingIdentity();
14000            int res = broadcastIntentLocked(callerApp,
14001                    callerApp != null ? callerApp.info.packageName : null,
14002                    intent, resolvedType, resultTo,
14003                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14004                    callingPid, callingUid, userId);
14005            Binder.restoreCallingIdentity(origId);
14006            return res;
14007        }
14008    }
14009
14010    int broadcastIntentInPackage(String packageName, int uid,
14011            Intent intent, String resolvedType, IIntentReceiver resultTo,
14012            int resultCode, String resultData, Bundle map,
14013            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14014        synchronized(this) {
14015            intent = verifyBroadcastLocked(intent);
14016
14017            final long origId = Binder.clearCallingIdentity();
14018            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14019                    resultTo, resultCode, resultData, map, requiredPermission,
14020                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14021            Binder.restoreCallingIdentity(origId);
14022            return res;
14023        }
14024    }
14025
14026    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14027        // Refuse possible leaked file descriptors
14028        if (intent != null && intent.hasFileDescriptors() == true) {
14029            throw new IllegalArgumentException("File descriptors passed in Intent");
14030        }
14031
14032        userId = handleIncomingUser(Binder.getCallingPid(),
14033                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14034
14035        synchronized(this) {
14036            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14037                    != PackageManager.PERMISSION_GRANTED) {
14038                String msg = "Permission Denial: unbroadcastIntent() from pid="
14039                        + Binder.getCallingPid()
14040                        + ", uid=" + Binder.getCallingUid()
14041                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14042                Slog.w(TAG, msg);
14043                throw new SecurityException(msg);
14044            }
14045            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14046            if (stickies != null) {
14047                ArrayList<Intent> list = stickies.get(intent.getAction());
14048                if (list != null) {
14049                    int N = list.size();
14050                    int i;
14051                    for (i=0; i<N; i++) {
14052                        if (intent.filterEquals(list.get(i))) {
14053                            list.remove(i);
14054                            break;
14055                        }
14056                    }
14057                    if (list.size() <= 0) {
14058                        stickies.remove(intent.getAction());
14059                    }
14060                }
14061                if (stickies.size() <= 0) {
14062                    mStickyBroadcasts.remove(userId);
14063                }
14064            }
14065        }
14066    }
14067
14068    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14069            String resultData, Bundle resultExtras, boolean resultAbort) {
14070        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14071        if (r == null) {
14072            Slog.w(TAG, "finishReceiver called but not found on queue");
14073            return false;
14074        }
14075
14076        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14077    }
14078
14079    void backgroundServicesFinishedLocked(int userId) {
14080        for (BroadcastQueue queue : mBroadcastQueues) {
14081            queue.backgroundServicesFinishedLocked(userId);
14082        }
14083    }
14084
14085    public void finishReceiver(IBinder who, int resultCode, String resultData,
14086            Bundle resultExtras, boolean resultAbort) {
14087        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14088
14089        // Refuse possible leaked file descriptors
14090        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14091            throw new IllegalArgumentException("File descriptors passed in Bundle");
14092        }
14093
14094        final long origId = Binder.clearCallingIdentity();
14095        try {
14096            boolean doNext = false;
14097            BroadcastRecord r;
14098
14099            synchronized(this) {
14100                r = broadcastRecordForReceiverLocked(who);
14101                if (r != null) {
14102                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14103                        resultData, resultExtras, resultAbort, true);
14104                }
14105            }
14106
14107            if (doNext) {
14108                r.queue.processNextBroadcast(false);
14109            }
14110            trimApplications();
14111        } finally {
14112            Binder.restoreCallingIdentity(origId);
14113        }
14114    }
14115
14116    // =========================================================
14117    // INSTRUMENTATION
14118    // =========================================================
14119
14120    public boolean startInstrumentation(ComponentName className,
14121            String profileFile, int flags, Bundle arguments,
14122            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14123            int userId) {
14124        enforceNotIsolatedCaller("startInstrumentation");
14125        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14126                userId, false, true, "startInstrumentation", null);
14127        // Refuse possible leaked file descriptors
14128        if (arguments != null && arguments.hasFileDescriptors()) {
14129            throw new IllegalArgumentException("File descriptors passed in Bundle");
14130        }
14131
14132        synchronized(this) {
14133            InstrumentationInfo ii = null;
14134            ApplicationInfo ai = null;
14135            try {
14136                ii = mContext.getPackageManager().getInstrumentationInfo(
14137                    className, STOCK_PM_FLAGS);
14138                ai = AppGlobals.getPackageManager().getApplicationInfo(
14139                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14140            } catch (PackageManager.NameNotFoundException e) {
14141            } catch (RemoteException e) {
14142            }
14143            if (ii == null) {
14144                reportStartInstrumentationFailure(watcher, className,
14145                        "Unable to find instrumentation info for: " + className);
14146                return false;
14147            }
14148            if (ai == null) {
14149                reportStartInstrumentationFailure(watcher, className,
14150                        "Unable to find instrumentation target package: " + ii.targetPackage);
14151                return false;
14152            }
14153
14154            int match = mContext.getPackageManager().checkSignatures(
14155                    ii.targetPackage, ii.packageName);
14156            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14157                String msg = "Permission Denial: starting instrumentation "
14158                        + className + " from pid="
14159                        + Binder.getCallingPid()
14160                        + ", uid=" + Binder.getCallingPid()
14161                        + " not allowed because package " + ii.packageName
14162                        + " does not have a signature matching the target "
14163                        + ii.targetPackage;
14164                reportStartInstrumentationFailure(watcher, className, msg);
14165                throw new SecurityException(msg);
14166            }
14167
14168            final long origId = Binder.clearCallingIdentity();
14169            // Instrumentation can kill and relaunch even persistent processes
14170            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14171                    "start instr");
14172            ProcessRecord app = addAppLocked(ai, false);
14173            app.instrumentationClass = className;
14174            app.instrumentationInfo = ai;
14175            app.instrumentationProfileFile = profileFile;
14176            app.instrumentationArguments = arguments;
14177            app.instrumentationWatcher = watcher;
14178            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14179            app.instrumentationResultClass = className;
14180            Binder.restoreCallingIdentity(origId);
14181        }
14182
14183        return true;
14184    }
14185
14186    /**
14187     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14188     * error to the logs, but if somebody is watching, send the report there too.  This enables
14189     * the "am" command to report errors with more information.
14190     *
14191     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14192     * @param cn The component name of the instrumentation.
14193     * @param report The error report.
14194     */
14195    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14196            ComponentName cn, String report) {
14197        Slog.w(TAG, report);
14198        try {
14199            if (watcher != null) {
14200                Bundle results = new Bundle();
14201                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14202                results.putString("Error", report);
14203                watcher.instrumentationStatus(cn, -1, results);
14204            }
14205        } catch (RemoteException e) {
14206            Slog.w(TAG, e);
14207        }
14208    }
14209
14210    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14211        if (app.instrumentationWatcher != null) {
14212            try {
14213                // NOTE:  IInstrumentationWatcher *must* be oneway here
14214                app.instrumentationWatcher.instrumentationFinished(
14215                    app.instrumentationClass,
14216                    resultCode,
14217                    results);
14218            } catch (RemoteException e) {
14219            }
14220        }
14221        if (app.instrumentationUiAutomationConnection != null) {
14222            try {
14223                app.instrumentationUiAutomationConnection.shutdown();
14224            } catch (RemoteException re) {
14225                /* ignore */
14226            }
14227            // Only a UiAutomation can set this flag and now that
14228            // it is finished we make sure it is reset to its default.
14229            mUserIsMonkey = false;
14230        }
14231        app.instrumentationWatcher = null;
14232        app.instrumentationUiAutomationConnection = null;
14233        app.instrumentationClass = null;
14234        app.instrumentationInfo = null;
14235        app.instrumentationProfileFile = null;
14236        app.instrumentationArguments = null;
14237
14238        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14239                "finished inst");
14240    }
14241
14242    public void finishInstrumentation(IApplicationThread target,
14243            int resultCode, Bundle results) {
14244        int userId = UserHandle.getCallingUserId();
14245        // Refuse possible leaked file descriptors
14246        if (results != null && results.hasFileDescriptors()) {
14247            throw new IllegalArgumentException("File descriptors passed in Intent");
14248        }
14249
14250        synchronized(this) {
14251            ProcessRecord app = getRecordForAppLocked(target);
14252            if (app == null) {
14253                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14254                return;
14255            }
14256            final long origId = Binder.clearCallingIdentity();
14257            finishInstrumentationLocked(app, resultCode, results);
14258            Binder.restoreCallingIdentity(origId);
14259        }
14260    }
14261
14262    // =========================================================
14263    // CONFIGURATION
14264    // =========================================================
14265
14266    public ConfigurationInfo getDeviceConfigurationInfo() {
14267        ConfigurationInfo config = new ConfigurationInfo();
14268        synchronized (this) {
14269            config.reqTouchScreen = mConfiguration.touchscreen;
14270            config.reqKeyboardType = mConfiguration.keyboard;
14271            config.reqNavigation = mConfiguration.navigation;
14272            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14273                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14274                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14275            }
14276            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14277                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14278                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14279            }
14280            config.reqGlEsVersion = GL_ES_VERSION;
14281        }
14282        return config;
14283    }
14284
14285    ActivityStack getFocusedStack() {
14286        return mStackSupervisor.getFocusedStack();
14287    }
14288
14289    public Configuration getConfiguration() {
14290        Configuration ci;
14291        synchronized(this) {
14292            ci = new Configuration(mConfiguration);
14293        }
14294        return ci;
14295    }
14296
14297    public void updatePersistentConfiguration(Configuration values) {
14298        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14299                "updateConfiguration()");
14300        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14301                "updateConfiguration()");
14302        if (values == null) {
14303            throw new NullPointerException("Configuration must not be null");
14304        }
14305
14306        synchronized(this) {
14307            final long origId = Binder.clearCallingIdentity();
14308            updateConfigurationLocked(values, null, true, false);
14309            Binder.restoreCallingIdentity(origId);
14310        }
14311    }
14312
14313    public void updateConfiguration(Configuration values) {
14314        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14315                "updateConfiguration()");
14316
14317        synchronized(this) {
14318            if (values == null && mWindowManager != null) {
14319                // sentinel: fetch the current configuration from the window manager
14320                values = mWindowManager.computeNewConfiguration();
14321            }
14322
14323            if (mWindowManager != null) {
14324                mProcessList.applyDisplaySize(mWindowManager);
14325            }
14326
14327            final long origId = Binder.clearCallingIdentity();
14328            if (values != null) {
14329                Settings.System.clearConfiguration(values);
14330            }
14331            updateConfigurationLocked(values, null, false, false);
14332            Binder.restoreCallingIdentity(origId);
14333        }
14334    }
14335
14336    /**
14337     * Do either or both things: (1) change the current configuration, and (2)
14338     * make sure the given activity is running with the (now) current
14339     * configuration.  Returns true if the activity has been left running, or
14340     * false if <var>starting</var> is being destroyed to match the new
14341     * configuration.
14342     * @param persistent TODO
14343     */
14344    boolean updateConfigurationLocked(Configuration values,
14345            ActivityRecord starting, boolean persistent, boolean initLocale) {
14346        int changes = 0;
14347
14348        if (values != null) {
14349            Configuration newConfig = new Configuration(mConfiguration);
14350            changes = newConfig.updateFrom(values);
14351            if (changes != 0) {
14352                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14353                    Slog.i(TAG, "Updating configuration to: " + values);
14354                }
14355
14356                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14357
14358                if (values.locale != null && !initLocale) {
14359                    saveLocaleLocked(values.locale,
14360                                     !values.locale.equals(mConfiguration.locale),
14361                                     values.userSetLocale);
14362                }
14363
14364                mConfigurationSeq++;
14365                if (mConfigurationSeq <= 0) {
14366                    mConfigurationSeq = 1;
14367                }
14368                newConfig.seq = mConfigurationSeq;
14369                mConfiguration = newConfig;
14370                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14371
14372                final Configuration configCopy = new Configuration(mConfiguration);
14373
14374                // TODO: If our config changes, should we auto dismiss any currently
14375                // showing dialogs?
14376                mShowDialogs = shouldShowDialogs(newConfig);
14377
14378                AttributeCache ac = AttributeCache.instance();
14379                if (ac != null) {
14380                    ac.updateConfiguration(configCopy);
14381                }
14382
14383                // Make sure all resources in our process are updated
14384                // right now, so that anyone who is going to retrieve
14385                // resource values after we return will be sure to get
14386                // the new ones.  This is especially important during
14387                // boot, where the first config change needs to guarantee
14388                // all resources have that config before following boot
14389                // code is executed.
14390                mSystemThread.applyConfigurationToResources(configCopy);
14391
14392                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14393                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14394                    msg.obj = new Configuration(configCopy);
14395                    mHandler.sendMessage(msg);
14396                }
14397
14398                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14399                    ProcessRecord app = mLruProcesses.get(i);
14400                    try {
14401                        if (app.thread != null) {
14402                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14403                                    + app.processName + " new config " + mConfiguration);
14404                            app.thread.scheduleConfigurationChanged(configCopy);
14405                        }
14406                    } catch (Exception e) {
14407                    }
14408                }
14409                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14410                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14411                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14412                        | Intent.FLAG_RECEIVER_FOREGROUND);
14413                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14414                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14415                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14416                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14417                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14418                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14419                    broadcastIntentLocked(null, null, intent,
14420                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14421                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14422                }
14423            }
14424        }
14425
14426        boolean kept = true;
14427        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14428        // mainStack is null during startup.
14429        if (mainStack != null) {
14430            if (changes != 0 && starting == null) {
14431                // If the configuration changed, and the caller is not already
14432                // in the process of starting an activity, then find the top
14433                // activity to check if its configuration needs to change.
14434                starting = mainStack.topRunningActivityLocked(null);
14435            }
14436
14437            if (starting != null) {
14438                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14439                // And we need to make sure at this point that all other activities
14440                // are made visible with the correct configuration.
14441                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14442            }
14443        }
14444
14445        if (values != null && mWindowManager != null) {
14446            mWindowManager.setNewConfiguration(mConfiguration);
14447        }
14448
14449        return kept;
14450    }
14451
14452    /**
14453     * Decide based on the configuration whether we should shouw the ANR,
14454     * crash, etc dialogs.  The idea is that if there is no affordnace to
14455     * press the on-screen buttons, we shouldn't show the dialog.
14456     *
14457     * A thought: SystemUI might also want to get told about this, the Power
14458     * dialog / global actions also might want different behaviors.
14459     */
14460    private static final boolean shouldShowDialogs(Configuration config) {
14461        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14462                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14463    }
14464
14465    /**
14466     * Save the locale.  You must be inside a synchronized (this) block.
14467     */
14468    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14469        if(isDiff) {
14470            SystemProperties.set("user.language", l.getLanguage());
14471            SystemProperties.set("user.region", l.getCountry());
14472        }
14473
14474        if(isPersist) {
14475            SystemProperties.set("persist.sys.language", l.getLanguage());
14476            SystemProperties.set("persist.sys.country", l.getCountry());
14477            SystemProperties.set("persist.sys.localevar", l.getVariant());
14478        }
14479    }
14480
14481    @Override
14482    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14483        ActivityRecord srec = ActivityRecord.forToken(token);
14484        return srec != null && srec.task.affinity != null &&
14485                srec.task.affinity.equals(destAffinity);
14486    }
14487
14488    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14489            Intent resultData) {
14490
14491        synchronized (this) {
14492            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14493            if (stack != null) {
14494                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14495            }
14496            return false;
14497        }
14498    }
14499
14500    public int getLaunchedFromUid(IBinder activityToken) {
14501        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14502        if (srec == null) {
14503            return -1;
14504        }
14505        return srec.launchedFromUid;
14506    }
14507
14508    public String getLaunchedFromPackage(IBinder activityToken) {
14509        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14510        if (srec == null) {
14511            return null;
14512        }
14513        return srec.launchedFromPackage;
14514    }
14515
14516    // =========================================================
14517    // LIFETIME MANAGEMENT
14518    // =========================================================
14519
14520    // Returns which broadcast queue the app is the current [or imminent] receiver
14521    // on, or 'null' if the app is not an active broadcast recipient.
14522    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14523        BroadcastRecord r = app.curReceiver;
14524        if (r != null) {
14525            return r.queue;
14526        }
14527
14528        // It's not the current receiver, but it might be starting up to become one
14529        synchronized (this) {
14530            for (BroadcastQueue queue : mBroadcastQueues) {
14531                r = queue.mPendingBroadcast;
14532                if (r != null && r.curApp == app) {
14533                    // found it; report which queue it's in
14534                    return queue;
14535                }
14536            }
14537        }
14538
14539        return null;
14540    }
14541
14542    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14543            boolean doingAll, long now) {
14544        if (mAdjSeq == app.adjSeq) {
14545            // This adjustment has already been computed.
14546            return app.curRawAdj;
14547        }
14548
14549        if (app.thread == null) {
14550            app.adjSeq = mAdjSeq;
14551            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14552            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14553            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14554        }
14555
14556        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14557        app.adjSource = null;
14558        app.adjTarget = null;
14559        app.empty = false;
14560        app.cached = false;
14561
14562        final int activitiesSize = app.activities.size();
14563
14564        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14565            // The max adjustment doesn't allow this app to be anything
14566            // below foreground, so it is not worth doing work for it.
14567            app.adjType = "fixed";
14568            app.adjSeq = mAdjSeq;
14569            app.curRawAdj = app.maxAdj;
14570            app.foregroundActivities = false;
14571            app.keeping = true;
14572            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14573            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14574            // System processes can do UI, and when they do we want to have
14575            // them trim their memory after the user leaves the UI.  To
14576            // facilitate this, here we need to determine whether or not it
14577            // is currently showing UI.
14578            app.systemNoUi = true;
14579            if (app == TOP_APP) {
14580                app.systemNoUi = false;
14581            } else if (activitiesSize > 0) {
14582                for (int j = 0; j < activitiesSize; j++) {
14583                    final ActivityRecord r = app.activities.get(j);
14584                    if (r.visible) {
14585                        app.systemNoUi = false;
14586                    }
14587                }
14588            }
14589            if (!app.systemNoUi) {
14590                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14591            }
14592            return (app.curAdj=app.maxAdj);
14593        }
14594
14595        app.keeping = false;
14596        app.systemNoUi = false;
14597
14598        // Determine the importance of the process, starting with most
14599        // important to least, and assign an appropriate OOM adjustment.
14600        int adj;
14601        int schedGroup;
14602        int procState;
14603        boolean foregroundActivities = false;
14604        boolean interesting = false;
14605        BroadcastQueue queue;
14606        if (app == TOP_APP) {
14607            // The last app on the list is the foreground app.
14608            adj = ProcessList.FOREGROUND_APP_ADJ;
14609            schedGroup = Process.THREAD_GROUP_DEFAULT;
14610            app.adjType = "top-activity";
14611            foregroundActivities = true;
14612            interesting = true;
14613            procState = ActivityManager.PROCESS_STATE_TOP;
14614        } else if (app.instrumentationClass != null) {
14615            // Don't want to kill running instrumentation.
14616            adj = ProcessList.FOREGROUND_APP_ADJ;
14617            schedGroup = Process.THREAD_GROUP_DEFAULT;
14618            app.adjType = "instrumentation";
14619            interesting = true;
14620            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14621        } else if ((queue = isReceivingBroadcast(app)) != null) {
14622            // An app that is currently receiving a broadcast also
14623            // counts as being in the foreground for OOM killer purposes.
14624            // It's placed in a sched group based on the nature of the
14625            // broadcast as reflected by which queue it's active in.
14626            adj = ProcessList.FOREGROUND_APP_ADJ;
14627            schedGroup = (queue == mFgBroadcastQueue)
14628                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14629            app.adjType = "broadcast";
14630            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14631        } else if (app.executingServices.size() > 0) {
14632            // An app that is currently executing a service callback also
14633            // counts as being in the foreground.
14634            adj = ProcessList.FOREGROUND_APP_ADJ;
14635            schedGroup = app.execServicesFg ?
14636                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14637            app.adjType = "exec-service";
14638            procState = ActivityManager.PROCESS_STATE_SERVICE;
14639            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14640        } else {
14641            // As far as we know the process is empty.  We may change our mind later.
14642            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14643            // At this point we don't actually know the adjustment.  Use the cached adj
14644            // value that the caller wants us to.
14645            adj = cachedAdj;
14646            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14647            app.cached = true;
14648            app.empty = true;
14649            app.adjType = "cch-empty";
14650        }
14651
14652        // Examine all activities if not already foreground.
14653        if (!foregroundActivities && activitiesSize > 0) {
14654            for (int j = 0; j < activitiesSize; j++) {
14655                final ActivityRecord r = app.activities.get(j);
14656                if (r.app != app) {
14657                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14658                            + app + "?!?");
14659                    continue;
14660                }
14661                if (r.visible) {
14662                    // App has a visible activity; only upgrade adjustment.
14663                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14664                        adj = ProcessList.VISIBLE_APP_ADJ;
14665                        app.adjType = "visible";
14666                    }
14667                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14668                        procState = ActivityManager.PROCESS_STATE_TOP;
14669                    }
14670                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14671                    app.cached = false;
14672                    app.empty = false;
14673                    foregroundActivities = true;
14674                    break;
14675                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14676                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14677                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14678                        app.adjType = "pausing";
14679                    }
14680                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14681                        procState = ActivityManager.PROCESS_STATE_TOP;
14682                    }
14683                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14684                    app.cached = false;
14685                    app.empty = false;
14686                    foregroundActivities = true;
14687                } else if (r.state == ActivityState.STOPPING) {
14688                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14689                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14690                        app.adjType = "stopping";
14691                    }
14692                    // For the process state, we will at this point consider the
14693                    // process to be cached.  It will be cached either as an activity
14694                    // or empty depending on whether the activity is finishing.  We do
14695                    // this so that we can treat the process as cached for purposes of
14696                    // memory trimming (determing current memory level, trim command to
14697                    // send to process) since there can be an arbitrary number of stopping
14698                    // processes and they should soon all go into the cached state.
14699                    if (!r.finishing) {
14700                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14701                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14702                        }
14703                    }
14704                    app.cached = false;
14705                    app.empty = false;
14706                    foregroundActivities = true;
14707                } else {
14708                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14709                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14710                        app.adjType = "cch-act";
14711                    }
14712                }
14713            }
14714        }
14715
14716        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14717            if (app.foregroundServices) {
14718                // The user is aware of this app, so make it visible.
14719                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14720                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14721                app.cached = false;
14722                app.adjType = "fg-service";
14723                schedGroup = Process.THREAD_GROUP_DEFAULT;
14724            } else if (app.forcingToForeground != null) {
14725                // The user is aware of this app, so make it visible.
14726                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14727                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14728                app.cached = false;
14729                app.adjType = "force-fg";
14730                app.adjSource = app.forcingToForeground;
14731                schedGroup = Process.THREAD_GROUP_DEFAULT;
14732            }
14733        }
14734
14735        if (app.foregroundServices) {
14736            interesting = true;
14737        }
14738
14739        if (app == mHeavyWeightProcess) {
14740            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14741                // We don't want to kill the current heavy-weight process.
14742                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14743                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14744                app.cached = false;
14745                app.adjType = "heavy";
14746            }
14747            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14748                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14749            }
14750        }
14751
14752        if (app == mHomeProcess) {
14753            if (adj > ProcessList.HOME_APP_ADJ) {
14754                // This process is hosting what we currently consider to be the
14755                // home app, so we don't want to let it go into the background.
14756                adj = ProcessList.HOME_APP_ADJ;
14757                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14758                app.cached = false;
14759                app.adjType = "home";
14760            }
14761            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14762                procState = ActivityManager.PROCESS_STATE_HOME;
14763            }
14764        }
14765
14766        if (app == mPreviousProcess && app.activities.size() > 0) {
14767            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14768                // This was the previous process that showed UI to the user.
14769                // We want to try to keep it around more aggressively, to give
14770                // a good experience around switching between two apps.
14771                adj = ProcessList.PREVIOUS_APP_ADJ;
14772                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14773                app.cached = false;
14774                app.adjType = "previous";
14775            }
14776            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14777                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14778            }
14779        }
14780
14781        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14782                + " reason=" + app.adjType);
14783
14784        // By default, we use the computed adjustment.  It may be changed if
14785        // there are applications dependent on our services or providers, but
14786        // this gives us a baseline and makes sure we don't get into an
14787        // infinite recursion.
14788        app.adjSeq = mAdjSeq;
14789        app.curRawAdj = adj;
14790        app.hasStartedServices = false;
14791
14792        if (mBackupTarget != null && app == mBackupTarget.app) {
14793            // If possible we want to avoid killing apps while they're being backed up
14794            if (adj > ProcessList.BACKUP_APP_ADJ) {
14795                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14796                adj = ProcessList.BACKUP_APP_ADJ;
14797                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14798                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14799                }
14800                app.adjType = "backup";
14801                app.cached = false;
14802            }
14803            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14804                procState = ActivityManager.PROCESS_STATE_BACKUP;
14805            }
14806        }
14807
14808        boolean mayBeTop = false;
14809
14810        for (int is = app.services.size()-1;
14811                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14812                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14813                        || procState > ActivityManager.PROCESS_STATE_TOP);
14814                is--) {
14815            ServiceRecord s = app.services.valueAt(is);
14816            if (s.startRequested) {
14817                app.hasStartedServices = true;
14818                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14819                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14820                }
14821                if (app.hasShownUi && app != mHomeProcess) {
14822                    // If this process has shown some UI, let it immediately
14823                    // go to the LRU list because it may be pretty heavy with
14824                    // UI stuff.  We'll tag it with a label just to help
14825                    // debug and understand what is going on.
14826                    if (adj > ProcessList.SERVICE_ADJ) {
14827                        app.adjType = "cch-started-ui-services";
14828                    }
14829                } else {
14830                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14831                        // This service has seen some activity within
14832                        // recent memory, so we will keep its process ahead
14833                        // of the background processes.
14834                        if (adj > ProcessList.SERVICE_ADJ) {
14835                            adj = ProcessList.SERVICE_ADJ;
14836                            app.adjType = "started-services";
14837                            app.cached = false;
14838                        }
14839                    }
14840                    // If we have let the service slide into the background
14841                    // state, still have some text describing what it is doing
14842                    // even though the service no longer has an impact.
14843                    if (adj > ProcessList.SERVICE_ADJ) {
14844                        app.adjType = "cch-started-services";
14845                    }
14846                }
14847                // Don't kill this process because it is doing work; it
14848                // has said it is doing work.
14849                app.keeping = true;
14850            }
14851            for (int conni = s.connections.size()-1;
14852                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14853                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14854                            || procState > ActivityManager.PROCESS_STATE_TOP);
14855                    conni--) {
14856                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14857                for (int i = 0;
14858                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14859                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14860                                || procState > ActivityManager.PROCESS_STATE_TOP);
14861                        i++) {
14862                    // XXX should compute this based on the max of
14863                    // all connected clients.
14864                    ConnectionRecord cr = clist.get(i);
14865                    if (cr.binding.client == app) {
14866                        // Binding to ourself is not interesting.
14867                        continue;
14868                    }
14869                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14870                        ProcessRecord client = cr.binding.client;
14871                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14872                                TOP_APP, doingAll, now);
14873                        int clientProcState = client.curProcState;
14874                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14875                            // If the other app is cached for any reason, for purposes here
14876                            // we are going to consider it empty.  The specific cached state
14877                            // doesn't propagate except under certain conditions.
14878                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14879                        }
14880                        String adjType = null;
14881                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14882                            // Not doing bind OOM management, so treat
14883                            // this guy more like a started service.
14884                            if (app.hasShownUi && app != mHomeProcess) {
14885                                // If this process has shown some UI, let it immediately
14886                                // go to the LRU list because it may be pretty heavy with
14887                                // UI stuff.  We'll tag it with a label just to help
14888                                // debug and understand what is going on.
14889                                if (adj > clientAdj) {
14890                                    adjType = "cch-bound-ui-services";
14891                                }
14892                                app.cached = false;
14893                                clientAdj = adj;
14894                                clientProcState = procState;
14895                            } else {
14896                                if (now >= (s.lastActivity
14897                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14898                                    // This service has not seen activity within
14899                                    // recent memory, so allow it to drop to the
14900                                    // LRU list if there is no other reason to keep
14901                                    // it around.  We'll also tag it with a label just
14902                                    // to help debug and undertand what is going on.
14903                                    if (adj > clientAdj) {
14904                                        adjType = "cch-bound-services";
14905                                    }
14906                                    clientAdj = adj;
14907                                }
14908                            }
14909                        }
14910                        if (adj > clientAdj) {
14911                            // If this process has recently shown UI, and
14912                            // the process that is binding to it is less
14913                            // important than being visible, then we don't
14914                            // care about the binding as much as we care
14915                            // about letting this process get into the LRU
14916                            // list to be killed and restarted if needed for
14917                            // memory.
14918                            if (app.hasShownUi && app != mHomeProcess
14919                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14920                                adjType = "cch-bound-ui-services";
14921                            } else {
14922                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14923                                        |Context.BIND_IMPORTANT)) != 0) {
14924                                    adj = clientAdj;
14925                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14926                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14927                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14928                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14929                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14930                                    adj = clientAdj;
14931                                } else {
14932                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14933                                        adj = ProcessList.VISIBLE_APP_ADJ;
14934                                    }
14935                                }
14936                                if (!client.cached) {
14937                                    app.cached = false;
14938                                }
14939                                if (client.keeping) {
14940                                    app.keeping = true;
14941                                }
14942                                adjType = "service";
14943                            }
14944                        }
14945                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14946                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14947                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14948                            }
14949                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14950                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14951                                    // Special handling of clients who are in the top state.
14952                                    // We *may* want to consider this process to be in the
14953                                    // top state as well, but only if there is not another
14954                                    // reason for it to be running.  Being on the top is a
14955                                    // special state, meaning you are specifically running
14956                                    // for the current top app.  If the process is already
14957                                    // running in the background for some other reason, it
14958                                    // is more important to continue considering it to be
14959                                    // in the background state.
14960                                    mayBeTop = true;
14961                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14962                                } else {
14963                                    // Special handling for above-top states (persistent
14964                                    // processes).  These should not bring the current process
14965                                    // into the top state, since they are not on top.  Instead
14966                                    // give them the best state after that.
14967                                    clientProcState =
14968                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14969                                }
14970                            }
14971                        } else {
14972                            if (clientProcState <
14973                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14974                                clientProcState =
14975                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14976                            }
14977                        }
14978                        if (procState > clientProcState) {
14979                            procState = clientProcState;
14980                        }
14981                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14982                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14983                            app.pendingUiClean = true;
14984                        }
14985                        if (adjType != null) {
14986                            app.adjType = adjType;
14987                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14988                                    .REASON_SERVICE_IN_USE;
14989                            app.adjSource = cr.binding.client;
14990                            app.adjSourceOom = clientAdj;
14991                            app.adjTarget = s.name;
14992                        }
14993                    }
14994                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14995                        app.treatLikeActivity = true;
14996                    }
14997                    final ActivityRecord a = cr.activity;
14998                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14999                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15000                                (a.visible || a.state == ActivityState.RESUMED
15001                                 || a.state == ActivityState.PAUSING)) {
15002                            adj = ProcessList.FOREGROUND_APP_ADJ;
15003                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15004                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15005                            }
15006                            app.cached = false;
15007                            app.adjType = "service";
15008                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15009                                    .REASON_SERVICE_IN_USE;
15010                            app.adjSource = a;
15011                            app.adjSourceOom = adj;
15012                            app.adjTarget = s.name;
15013                        }
15014                    }
15015                }
15016            }
15017        }
15018
15019        for (int provi = app.pubProviders.size()-1;
15020                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15021                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15022                        || procState > ActivityManager.PROCESS_STATE_TOP);
15023                provi--) {
15024            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15025            for (int i = cpr.connections.size()-1;
15026                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15027                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15028                            || procState > ActivityManager.PROCESS_STATE_TOP);
15029                    i--) {
15030                ContentProviderConnection conn = cpr.connections.get(i);
15031                ProcessRecord client = conn.client;
15032                if (client == app) {
15033                    // Being our own client is not interesting.
15034                    continue;
15035                }
15036                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15037                int clientProcState = client.curProcState;
15038                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15039                    // If the other app is cached for any reason, for purposes here
15040                    // we are going to consider it empty.
15041                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15042                }
15043                if (adj > clientAdj) {
15044                    if (app.hasShownUi && app != mHomeProcess
15045                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15046                        app.adjType = "cch-ui-provider";
15047                    } else {
15048                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15049                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15050                        app.adjType = "provider";
15051                    }
15052                    app.cached &= client.cached;
15053                    app.keeping |= client.keeping;
15054                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15055                            .REASON_PROVIDER_IN_USE;
15056                    app.adjSource = client;
15057                    app.adjSourceOom = clientAdj;
15058                    app.adjTarget = cpr.name;
15059                }
15060                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15061                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15062                        // Special handling of clients who are in the top state.
15063                        // We *may* want to consider this process to be in the
15064                        // top state as well, but only if there is not another
15065                        // reason for it to be running.  Being on the top is a
15066                        // special state, meaning you are specifically running
15067                        // for the current top app.  If the process is already
15068                        // running in the background for some other reason, it
15069                        // is more important to continue considering it to be
15070                        // in the background state.
15071                        mayBeTop = true;
15072                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15073                    } else {
15074                        // Special handling for above-top states (persistent
15075                        // processes).  These should not bring the current process
15076                        // into the top state, since they are not on top.  Instead
15077                        // give them the best state after that.
15078                        clientProcState =
15079                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15080                    }
15081                }
15082                if (procState > clientProcState) {
15083                    procState = clientProcState;
15084                }
15085                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15086                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15087                }
15088            }
15089            // If the provider has external (non-framework) process
15090            // dependencies, ensure that its adjustment is at least
15091            // FOREGROUND_APP_ADJ.
15092            if (cpr.hasExternalProcessHandles()) {
15093                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15094                    adj = ProcessList.FOREGROUND_APP_ADJ;
15095                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15096                    app.cached = false;
15097                    app.keeping = true;
15098                    app.adjType = "provider";
15099                    app.adjTarget = cpr.name;
15100                }
15101                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15102                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15103                }
15104            }
15105        }
15106
15107        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15108            // A client of one of our services or providers is in the top state.  We
15109            // *may* want to be in the top state, but not if we are already running in
15110            // the background for some other reason.  For the decision here, we are going
15111            // to pick out a few specific states that we want to remain in when a client
15112            // is top (states that tend to be longer-term) and otherwise allow it to go
15113            // to the top state.
15114            switch (procState) {
15115                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15116                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15117                case ActivityManager.PROCESS_STATE_SERVICE:
15118                    // These all are longer-term states, so pull them up to the top
15119                    // of the background states, but not all the way to the top state.
15120                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15121                    break;
15122                default:
15123                    // Otherwise, top is a better choice, so take it.
15124                    procState = ActivityManager.PROCESS_STATE_TOP;
15125                    break;
15126            }
15127        }
15128
15129        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15130            if (app.hasClientActivities) {
15131                // This is a cached process, but with client activities.  Mark it so.
15132                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15133                app.adjType = "cch-client-act";
15134            } else if (app.treatLikeActivity) {
15135                // This is a cached process, but somebody wants us to treat it like it has
15136                // an activity, okay!
15137                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15138                app.adjType = "cch-as-act";
15139            }
15140        }
15141
15142        if (adj == ProcessList.SERVICE_ADJ) {
15143            if (doingAll) {
15144                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15145                mNewNumServiceProcs++;
15146                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15147                if (!app.serviceb) {
15148                    // This service isn't far enough down on the LRU list to
15149                    // normally be a B service, but if we are low on RAM and it
15150                    // is large we want to force it down since we would prefer to
15151                    // keep launcher over it.
15152                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15153                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15154                        app.serviceHighRam = true;
15155                        app.serviceb = true;
15156                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15157                    } else {
15158                        mNewNumAServiceProcs++;
15159                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15160                    }
15161                } else {
15162                    app.serviceHighRam = false;
15163                }
15164            }
15165            if (app.serviceb) {
15166                adj = ProcessList.SERVICE_B_ADJ;
15167            }
15168        }
15169
15170        app.curRawAdj = adj;
15171
15172        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15173        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15174        if (adj > app.maxAdj) {
15175            adj = app.maxAdj;
15176            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15177                schedGroup = Process.THREAD_GROUP_DEFAULT;
15178            }
15179        }
15180        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15181            app.keeping = true;
15182        }
15183
15184        // Do final modification to adj.  Everything we do between here and applying
15185        // the final setAdj must be done in this function, because we will also use
15186        // it when computing the final cached adj later.  Note that we don't need to
15187        // worry about this for max adj above, since max adj will always be used to
15188        // keep it out of the cached vaues.
15189        adj = app.modifyRawOomAdj(adj);
15190
15191        app.curProcState = procState;
15192        app.foregroundActivities = foregroundActivities;
15193
15194        return app.curRawAdj;
15195    }
15196
15197    /**
15198     * Schedule PSS collection of a process.
15199     */
15200    void requestPssLocked(ProcessRecord proc, int procState) {
15201        if (mPendingPssProcesses.contains(proc)) {
15202            return;
15203        }
15204        if (mPendingPssProcesses.size() == 0) {
15205            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15206        }
15207        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15208        proc.pssProcState = procState;
15209        mPendingPssProcesses.add(proc);
15210    }
15211
15212    /**
15213     * Schedule PSS collection of all processes.
15214     */
15215    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15216        if (!always) {
15217            if (now < (mLastFullPssTime +
15218                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15219                return;
15220            }
15221        }
15222        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15223        mLastFullPssTime = now;
15224        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15225        mPendingPssProcesses.clear();
15226        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15227            ProcessRecord app = mLruProcesses.get(i);
15228            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15229                app.pssProcState = app.setProcState;
15230                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15231                        isSleeping(), now);
15232                mPendingPssProcesses.add(app);
15233            }
15234        }
15235        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15236    }
15237
15238    /**
15239     * Ask a given process to GC right now.
15240     */
15241    final void performAppGcLocked(ProcessRecord app) {
15242        try {
15243            app.lastRequestedGc = SystemClock.uptimeMillis();
15244            if (app.thread != null) {
15245                if (app.reportLowMemory) {
15246                    app.reportLowMemory = false;
15247                    app.thread.scheduleLowMemory();
15248                } else {
15249                    app.thread.processInBackground();
15250                }
15251            }
15252        } catch (Exception e) {
15253            // whatever.
15254        }
15255    }
15256
15257    /**
15258     * Returns true if things are idle enough to perform GCs.
15259     */
15260    private final boolean canGcNowLocked() {
15261        boolean processingBroadcasts = false;
15262        for (BroadcastQueue q : mBroadcastQueues) {
15263            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15264                processingBroadcasts = true;
15265            }
15266        }
15267        return !processingBroadcasts
15268                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15269    }
15270
15271    /**
15272     * Perform GCs on all processes that are waiting for it, but only
15273     * if things are idle.
15274     */
15275    final void performAppGcsLocked() {
15276        final int N = mProcessesToGc.size();
15277        if (N <= 0) {
15278            return;
15279        }
15280        if (canGcNowLocked()) {
15281            while (mProcessesToGc.size() > 0) {
15282                ProcessRecord proc = mProcessesToGc.remove(0);
15283                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15284                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15285                            <= SystemClock.uptimeMillis()) {
15286                        // To avoid spamming the system, we will GC processes one
15287                        // at a time, waiting a few seconds between each.
15288                        performAppGcLocked(proc);
15289                        scheduleAppGcsLocked();
15290                        return;
15291                    } else {
15292                        // It hasn't been long enough since we last GCed this
15293                        // process...  put it in the list to wait for its time.
15294                        addProcessToGcListLocked(proc);
15295                        break;
15296                    }
15297                }
15298            }
15299
15300            scheduleAppGcsLocked();
15301        }
15302    }
15303
15304    /**
15305     * If all looks good, perform GCs on all processes waiting for them.
15306     */
15307    final void performAppGcsIfAppropriateLocked() {
15308        if (canGcNowLocked()) {
15309            performAppGcsLocked();
15310            return;
15311        }
15312        // Still not idle, wait some more.
15313        scheduleAppGcsLocked();
15314    }
15315
15316    /**
15317     * Schedule the execution of all pending app GCs.
15318     */
15319    final void scheduleAppGcsLocked() {
15320        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15321
15322        if (mProcessesToGc.size() > 0) {
15323            // Schedule a GC for the time to the next process.
15324            ProcessRecord proc = mProcessesToGc.get(0);
15325            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15326
15327            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15328            long now = SystemClock.uptimeMillis();
15329            if (when < (now+GC_TIMEOUT)) {
15330                when = now + GC_TIMEOUT;
15331            }
15332            mHandler.sendMessageAtTime(msg, when);
15333        }
15334    }
15335
15336    /**
15337     * Add a process to the array of processes waiting to be GCed.  Keeps the
15338     * list in sorted order by the last GC time.  The process can't already be
15339     * on the list.
15340     */
15341    final void addProcessToGcListLocked(ProcessRecord proc) {
15342        boolean added = false;
15343        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15344            if (mProcessesToGc.get(i).lastRequestedGc <
15345                    proc.lastRequestedGc) {
15346                added = true;
15347                mProcessesToGc.add(i+1, proc);
15348                break;
15349            }
15350        }
15351        if (!added) {
15352            mProcessesToGc.add(0, proc);
15353        }
15354    }
15355
15356    /**
15357     * Set up to ask a process to GC itself.  This will either do it
15358     * immediately, or put it on the list of processes to gc the next
15359     * time things are idle.
15360     */
15361    final void scheduleAppGcLocked(ProcessRecord app) {
15362        long now = SystemClock.uptimeMillis();
15363        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15364            return;
15365        }
15366        if (!mProcessesToGc.contains(app)) {
15367            addProcessToGcListLocked(app);
15368            scheduleAppGcsLocked();
15369        }
15370    }
15371
15372    final void checkExcessivePowerUsageLocked(boolean doKills) {
15373        updateCpuStatsNow();
15374
15375        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15376        boolean doWakeKills = doKills;
15377        boolean doCpuKills = doKills;
15378        if (mLastPowerCheckRealtime == 0) {
15379            doWakeKills = false;
15380        }
15381        if (mLastPowerCheckUptime == 0) {
15382            doCpuKills = false;
15383        }
15384        if (stats.isScreenOn()) {
15385            doWakeKills = false;
15386        }
15387        final long curRealtime = SystemClock.elapsedRealtime();
15388        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15389        final long curUptime = SystemClock.uptimeMillis();
15390        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15391        mLastPowerCheckRealtime = curRealtime;
15392        mLastPowerCheckUptime = curUptime;
15393        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15394            doWakeKills = false;
15395        }
15396        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15397            doCpuKills = false;
15398        }
15399        int i = mLruProcesses.size();
15400        while (i > 0) {
15401            i--;
15402            ProcessRecord app = mLruProcesses.get(i);
15403            if (!app.keeping) {
15404                long wtime;
15405                synchronized (stats) {
15406                    wtime = stats.getProcessWakeTime(app.info.uid,
15407                            app.pid, curRealtime);
15408                }
15409                long wtimeUsed = wtime - app.lastWakeTime;
15410                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15411                if (DEBUG_POWER) {
15412                    StringBuilder sb = new StringBuilder(128);
15413                    sb.append("Wake for ");
15414                    app.toShortString(sb);
15415                    sb.append(": over ");
15416                    TimeUtils.formatDuration(realtimeSince, sb);
15417                    sb.append(" used ");
15418                    TimeUtils.formatDuration(wtimeUsed, sb);
15419                    sb.append(" (");
15420                    sb.append((wtimeUsed*100)/realtimeSince);
15421                    sb.append("%)");
15422                    Slog.i(TAG, sb.toString());
15423                    sb.setLength(0);
15424                    sb.append("CPU for ");
15425                    app.toShortString(sb);
15426                    sb.append(": over ");
15427                    TimeUtils.formatDuration(uptimeSince, sb);
15428                    sb.append(" used ");
15429                    TimeUtils.formatDuration(cputimeUsed, sb);
15430                    sb.append(" (");
15431                    sb.append((cputimeUsed*100)/uptimeSince);
15432                    sb.append("%)");
15433                    Slog.i(TAG, sb.toString());
15434                }
15435                // If a process has held a wake lock for more
15436                // than 50% of the time during this period,
15437                // that sounds bad.  Kill!
15438                if (doWakeKills && realtimeSince > 0
15439                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15440                    synchronized (stats) {
15441                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15442                                realtimeSince, wtimeUsed);
15443                    }
15444                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15445                            + " during " + realtimeSince);
15446                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15447                } else if (doCpuKills && uptimeSince > 0
15448                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15449                    synchronized (stats) {
15450                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15451                                uptimeSince, cputimeUsed);
15452                    }
15453                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15454                            + " during " + uptimeSince);
15455                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15456                } else {
15457                    app.lastWakeTime = wtime;
15458                    app.lastCpuTime = app.curCpuTime;
15459                }
15460            }
15461        }
15462    }
15463
15464    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15465            ProcessRecord TOP_APP, boolean doingAll, long now) {
15466        boolean success = true;
15467
15468        if (app.curRawAdj != app.setRawAdj) {
15469            if (wasKeeping && !app.keeping) {
15470                // This app is no longer something we want to keep.  Note
15471                // its current wake lock time to later know to kill it if
15472                // it is not behaving well.
15473                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15474                synchronized (stats) {
15475                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15476                            app.pid, SystemClock.elapsedRealtime());
15477                }
15478                app.lastCpuTime = app.curCpuTime;
15479            }
15480
15481            app.setRawAdj = app.curRawAdj;
15482        }
15483
15484        int changes = 0;
15485
15486        if (app.curAdj != app.setAdj) {
15487            ProcessList.setOomAdj(app.pid, app.curAdj);
15488            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15489                TAG, "Set " + app.pid + " " + app.processName +
15490                " adj " + app.curAdj + ": " + app.adjType);
15491            app.setAdj = app.curAdj;
15492        }
15493
15494        if (app.setSchedGroup != app.curSchedGroup) {
15495            app.setSchedGroup = app.curSchedGroup;
15496            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15497                    "Setting process group of " + app.processName
15498                    + " to " + app.curSchedGroup);
15499            if (app.waitingToKill != null &&
15500                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15501                killUnneededProcessLocked(app, app.waitingToKill);
15502                success = false;
15503            } else {
15504                if (true) {
15505                    long oldId = Binder.clearCallingIdentity();
15506                    try {
15507                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15508                    } catch (Exception e) {
15509                        Slog.w(TAG, "Failed setting process group of " + app.pid
15510                                + " to " + app.curSchedGroup);
15511                        e.printStackTrace();
15512                    } finally {
15513                        Binder.restoreCallingIdentity(oldId);
15514                    }
15515                } else {
15516                    if (app.thread != null) {
15517                        try {
15518                            app.thread.setSchedulingGroup(app.curSchedGroup);
15519                        } catch (RemoteException e) {
15520                        }
15521                    }
15522                }
15523                Process.setSwappiness(app.pid,
15524                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15525            }
15526        }
15527        if (app.repForegroundActivities != app.foregroundActivities) {
15528            app.repForegroundActivities = app.foregroundActivities;
15529            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15530        }
15531        if (app.repProcState != app.curProcState) {
15532            app.repProcState = app.curProcState;
15533            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15534            if (app.thread != null) {
15535                try {
15536                    if (false) {
15537                        //RuntimeException h = new RuntimeException("here");
15538                        Slog.i(TAG, "Sending new process state " + app.repProcState
15539                                + " to " + app /*, h*/);
15540                    }
15541                    app.thread.setProcessState(app.repProcState);
15542                } catch (RemoteException e) {
15543                }
15544            }
15545        }
15546        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15547                app.setProcState)) {
15548            app.lastStateTime = now;
15549            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15550                    isSleeping(), now);
15551            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15552                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15553                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15554                    + (app.nextPssTime-now) + ": " + app);
15555        } else {
15556            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15557                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15558                requestPssLocked(app, app.setProcState);
15559                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15560                        isSleeping(), now);
15561            } else if (false && DEBUG_PSS) {
15562                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15563            }
15564        }
15565        if (app.setProcState != app.curProcState) {
15566            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15567                    "Proc state change of " + app.processName
15568                    + " to " + app.curProcState);
15569            app.setProcState = app.curProcState;
15570            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15571                app.notCachedSinceIdle = false;
15572            }
15573            if (!doingAll) {
15574                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15575            } else {
15576                app.procStateChanged = true;
15577            }
15578        }
15579
15580        if (changes != 0) {
15581            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15582            int i = mPendingProcessChanges.size()-1;
15583            ProcessChangeItem item = null;
15584            while (i >= 0) {
15585                item = mPendingProcessChanges.get(i);
15586                if (item.pid == app.pid) {
15587                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15588                    break;
15589                }
15590                i--;
15591            }
15592            if (i < 0) {
15593                // No existing item in pending changes; need a new one.
15594                final int NA = mAvailProcessChanges.size();
15595                if (NA > 0) {
15596                    item = mAvailProcessChanges.remove(NA-1);
15597                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15598                } else {
15599                    item = new ProcessChangeItem();
15600                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15601                }
15602                item.changes = 0;
15603                item.pid = app.pid;
15604                item.uid = app.info.uid;
15605                if (mPendingProcessChanges.size() == 0) {
15606                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15607                            "*** Enqueueing dispatch processes changed!");
15608                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15609                }
15610                mPendingProcessChanges.add(item);
15611            }
15612            item.changes |= changes;
15613            item.processState = app.repProcState;
15614            item.foregroundActivities = app.repForegroundActivities;
15615            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15616                    + Integer.toHexString(System.identityHashCode(item))
15617                    + " " + app.toShortString() + ": changes=" + item.changes
15618                    + " procState=" + item.processState
15619                    + " foreground=" + item.foregroundActivities
15620                    + " type=" + app.adjType + " source=" + app.adjSource
15621                    + " target=" + app.adjTarget);
15622        }
15623
15624        return success;
15625    }
15626
15627    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15628        if (proc.thread != null && proc.baseProcessTracker != null) {
15629            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15630        }
15631    }
15632
15633    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15634            ProcessRecord TOP_APP, boolean doingAll, long now) {
15635        if (app.thread == null) {
15636            return false;
15637        }
15638
15639        final boolean wasKeeping = app.keeping;
15640
15641        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15642
15643        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15644    }
15645
15646    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15647            boolean oomAdj) {
15648        if (isForeground != proc.foregroundServices) {
15649            proc.foregroundServices = isForeground;
15650            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15651                    proc.info.uid);
15652            if (isForeground) {
15653                if (curProcs == null) {
15654                    curProcs = new ArrayList<ProcessRecord>();
15655                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15656                }
15657                if (!curProcs.contains(proc)) {
15658                    curProcs.add(proc);
15659                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15660                            proc.info.packageName, proc.info.uid);
15661                }
15662            } else {
15663                if (curProcs != null) {
15664                    if (curProcs.remove(proc)) {
15665                        mBatteryStatsService.noteEvent(
15666                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15667                                proc.info.packageName, proc.info.uid);
15668                        if (curProcs.size() <= 0) {
15669                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15670                        }
15671                    }
15672                }
15673            }
15674            if (oomAdj) {
15675                updateOomAdjLocked();
15676            }
15677        }
15678    }
15679
15680    private final ActivityRecord resumedAppLocked() {
15681        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15682        String pkg;
15683        int uid;
15684        if (act != null && !act.sleeping) {
15685            pkg = act.packageName;
15686            uid = act.info.applicationInfo.uid;
15687        } else {
15688            pkg = null;
15689            uid = -1;
15690        }
15691        // Has the UID or resumed package name changed?
15692        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15693                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15694            if (mCurResumedPackage != null) {
15695                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15696                        mCurResumedPackage, mCurResumedUid);
15697            }
15698            mCurResumedPackage = pkg;
15699            mCurResumedUid = uid;
15700            if (mCurResumedPackage != null) {
15701                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15702                        mCurResumedPackage, mCurResumedUid);
15703            }
15704        }
15705        return act;
15706    }
15707
15708    final boolean updateOomAdjLocked(ProcessRecord app) {
15709        final ActivityRecord TOP_ACT = resumedAppLocked();
15710        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15711        final boolean wasCached = app.cached;
15712
15713        mAdjSeq++;
15714
15715        // This is the desired cached adjusment we want to tell it to use.
15716        // If our app is currently cached, we know it, and that is it.  Otherwise,
15717        // we don't know it yet, and it needs to now be cached we will then
15718        // need to do a complete oom adj.
15719        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15720                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15721        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15722                SystemClock.uptimeMillis());
15723        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15724            // Changed to/from cached state, so apps after it in the LRU
15725            // list may also be changed.
15726            updateOomAdjLocked();
15727        }
15728        return success;
15729    }
15730
15731    final void updateOomAdjLocked() {
15732        final ActivityRecord TOP_ACT = resumedAppLocked();
15733        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15734        final long now = SystemClock.uptimeMillis();
15735        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15736        final int N = mLruProcesses.size();
15737
15738        if (false) {
15739            RuntimeException e = new RuntimeException();
15740            e.fillInStackTrace();
15741            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15742        }
15743
15744        mAdjSeq++;
15745        mNewNumServiceProcs = 0;
15746        mNewNumAServiceProcs = 0;
15747
15748        final int emptyProcessLimit;
15749        final int cachedProcessLimit;
15750        if (mProcessLimit <= 0) {
15751            emptyProcessLimit = cachedProcessLimit = 0;
15752        } else if (mProcessLimit == 1) {
15753            emptyProcessLimit = 1;
15754            cachedProcessLimit = 0;
15755        } else {
15756            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15757            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15758        }
15759
15760        // Let's determine how many processes we have running vs.
15761        // how many slots we have for background processes; we may want
15762        // to put multiple processes in a slot of there are enough of
15763        // them.
15764        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15765                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15766        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15767        if (numEmptyProcs > cachedProcessLimit) {
15768            // If there are more empty processes than our limit on cached
15769            // processes, then use the cached process limit for the factor.
15770            // This ensures that the really old empty processes get pushed
15771            // down to the bottom, so if we are running low on memory we will
15772            // have a better chance at keeping around more cached processes
15773            // instead of a gazillion empty processes.
15774            numEmptyProcs = cachedProcessLimit;
15775        }
15776        int emptyFactor = numEmptyProcs/numSlots;
15777        if (emptyFactor < 1) emptyFactor = 1;
15778        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15779        if (cachedFactor < 1) cachedFactor = 1;
15780        int stepCached = 0;
15781        int stepEmpty = 0;
15782        int numCached = 0;
15783        int numEmpty = 0;
15784        int numTrimming = 0;
15785
15786        mNumNonCachedProcs = 0;
15787        mNumCachedHiddenProcs = 0;
15788
15789        // First update the OOM adjustment for each of the
15790        // application processes based on their current state.
15791        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15792        int nextCachedAdj = curCachedAdj+1;
15793        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15794        int nextEmptyAdj = curEmptyAdj+2;
15795        for (int i=N-1; i>=0; i--) {
15796            ProcessRecord app = mLruProcesses.get(i);
15797            if (!app.killedByAm && app.thread != null) {
15798                app.procStateChanged = false;
15799                final boolean wasKeeping = app.keeping;
15800                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15801
15802                // If we haven't yet assigned the final cached adj
15803                // to the process, do that now.
15804                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15805                    switch (app.curProcState) {
15806                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15807                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15808                            // This process is a cached process holding activities...
15809                            // assign it the next cached value for that type, and then
15810                            // step that cached level.
15811                            app.curRawAdj = curCachedAdj;
15812                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15813                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15814                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15815                                    + ")");
15816                            if (curCachedAdj != nextCachedAdj) {
15817                                stepCached++;
15818                                if (stepCached >= cachedFactor) {
15819                                    stepCached = 0;
15820                                    curCachedAdj = nextCachedAdj;
15821                                    nextCachedAdj += 2;
15822                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15823                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15824                                    }
15825                                }
15826                            }
15827                            break;
15828                        default:
15829                            // For everything else, assign next empty cached process
15830                            // level and bump that up.  Note that this means that
15831                            // long-running services that have dropped down to the
15832                            // cached level will be treated as empty (since their process
15833                            // state is still as a service), which is what we want.
15834                            app.curRawAdj = curEmptyAdj;
15835                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15836                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15837                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15838                                    + ")");
15839                            if (curEmptyAdj != nextEmptyAdj) {
15840                                stepEmpty++;
15841                                if (stepEmpty >= emptyFactor) {
15842                                    stepEmpty = 0;
15843                                    curEmptyAdj = nextEmptyAdj;
15844                                    nextEmptyAdj += 2;
15845                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15846                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15847                                    }
15848                                }
15849                            }
15850                            break;
15851                    }
15852                }
15853
15854                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15855
15856                // Count the number of process types.
15857                switch (app.curProcState) {
15858                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15859                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15860                        mNumCachedHiddenProcs++;
15861                        numCached++;
15862                        if (numCached > cachedProcessLimit) {
15863                            killUnneededProcessLocked(app, "cached #" + numCached);
15864                        }
15865                        break;
15866                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15867                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15868                                && app.lastActivityTime < oldTime) {
15869                            killUnneededProcessLocked(app, "empty for "
15870                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15871                                    / 1000) + "s");
15872                        } else {
15873                            numEmpty++;
15874                            if (numEmpty > emptyProcessLimit) {
15875                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15876                            }
15877                        }
15878                        break;
15879                    default:
15880                        mNumNonCachedProcs++;
15881                        break;
15882                }
15883
15884                if (app.isolated && app.services.size() <= 0) {
15885                    // If this is an isolated process, and there are no
15886                    // services running in it, then the process is no longer
15887                    // needed.  We agressively kill these because we can by
15888                    // definition not re-use the same process again, and it is
15889                    // good to avoid having whatever code was running in them
15890                    // left sitting around after no longer needed.
15891                    killUnneededProcessLocked(app, "isolated not needed");
15892                }
15893
15894                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15895                        && !app.killedByAm) {
15896                    numTrimming++;
15897                }
15898            }
15899        }
15900
15901        mNumServiceProcs = mNewNumServiceProcs;
15902
15903        // Now determine the memory trimming level of background processes.
15904        // Unfortunately we need to start at the back of the list to do this
15905        // properly.  We only do this if the number of background apps we
15906        // are managing to keep around is less than half the maximum we desire;
15907        // if we are keeping a good number around, we'll let them use whatever
15908        // memory they want.
15909        final int numCachedAndEmpty = numCached + numEmpty;
15910        int memFactor;
15911        if (numCached <= ProcessList.TRIM_CACHED_APPS
15912                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15913            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15914                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15915            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15916                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15917            } else {
15918                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15919            }
15920        } else {
15921            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15922        }
15923        // We always allow the memory level to go up (better).  We only allow it to go
15924        // down if we are in a state where that is allowed, *and* the total number of processes
15925        // has gone down since last time.
15926        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15927                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15928                + " last=" + mLastNumProcesses);
15929        if (memFactor > mLastMemoryLevel) {
15930            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15931                memFactor = mLastMemoryLevel;
15932                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15933            }
15934        }
15935        mLastMemoryLevel = memFactor;
15936        mLastNumProcesses = mLruProcesses.size();
15937        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15938        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15939        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15940            if (mLowRamStartTime == 0) {
15941                mLowRamStartTime = now;
15942            }
15943            int step = 0;
15944            int fgTrimLevel;
15945            switch (memFactor) {
15946                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15947                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15948                    break;
15949                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15950                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15951                    break;
15952                default:
15953                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15954                    break;
15955            }
15956            int factor = numTrimming/3;
15957            int minFactor = 2;
15958            if (mHomeProcess != null) minFactor++;
15959            if (mPreviousProcess != null) minFactor++;
15960            if (factor < minFactor) factor = minFactor;
15961            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15962            for (int i=N-1; i>=0; i--) {
15963                ProcessRecord app = mLruProcesses.get(i);
15964                if (allChanged || app.procStateChanged) {
15965                    setProcessTrackerState(app, trackerMemFactor, now);
15966                    app.procStateChanged = false;
15967                }
15968                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15969                        && !app.killedByAm) {
15970                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15971                        try {
15972                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15973                                    "Trimming memory of " + app.processName
15974                                    + " to " + curLevel);
15975                            app.thread.scheduleTrimMemory(curLevel);
15976                        } catch (RemoteException e) {
15977                        }
15978                        if (false) {
15979                            // For now we won't do this; our memory trimming seems
15980                            // to be good enough at this point that destroying
15981                            // activities causes more harm than good.
15982                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15983                                    && app != mHomeProcess && app != mPreviousProcess) {
15984                                // Need to do this on its own message because the stack may not
15985                                // be in a consistent state at this point.
15986                                // For these apps we will also finish their activities
15987                                // to help them free memory.
15988                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15989                            }
15990                        }
15991                    }
15992                    app.trimMemoryLevel = curLevel;
15993                    step++;
15994                    if (step >= factor) {
15995                        step = 0;
15996                        switch (curLevel) {
15997                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15998                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15999                                break;
16000                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16001                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16002                                break;
16003                        }
16004                    }
16005                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16006                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16007                            && app.thread != null) {
16008                        try {
16009                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16010                                    "Trimming memory of heavy-weight " + app.processName
16011                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16012                            app.thread.scheduleTrimMemory(
16013                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16014                        } catch (RemoteException e) {
16015                        }
16016                    }
16017                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16018                } else {
16019                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16020                            || app.systemNoUi) && app.pendingUiClean) {
16021                        // If this application is now in the background and it
16022                        // had done UI, then give it the special trim level to
16023                        // have it free UI resources.
16024                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16025                        if (app.trimMemoryLevel < level && app.thread != null) {
16026                            try {
16027                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16028                                        "Trimming memory of bg-ui " + app.processName
16029                                        + " to " + level);
16030                                app.thread.scheduleTrimMemory(level);
16031                            } catch (RemoteException e) {
16032                            }
16033                        }
16034                        app.pendingUiClean = false;
16035                    }
16036                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16037                        try {
16038                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16039                                    "Trimming memory of fg " + app.processName
16040                                    + " to " + fgTrimLevel);
16041                            app.thread.scheduleTrimMemory(fgTrimLevel);
16042                        } catch (RemoteException e) {
16043                        }
16044                    }
16045                    app.trimMemoryLevel = fgTrimLevel;
16046                }
16047            }
16048        } else {
16049            if (mLowRamStartTime != 0) {
16050                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16051                mLowRamStartTime = 0;
16052            }
16053            for (int i=N-1; i>=0; i--) {
16054                ProcessRecord app = mLruProcesses.get(i);
16055                if (allChanged || app.procStateChanged) {
16056                    setProcessTrackerState(app, trackerMemFactor, now);
16057                    app.procStateChanged = false;
16058                }
16059                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16060                        || app.systemNoUi) && app.pendingUiClean) {
16061                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16062                            && app.thread != null) {
16063                        try {
16064                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16065                                    "Trimming memory of ui hidden " + app.processName
16066                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16067                            app.thread.scheduleTrimMemory(
16068                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16069                        } catch (RemoteException e) {
16070                        }
16071                    }
16072                    app.pendingUiClean = false;
16073                }
16074                app.trimMemoryLevel = 0;
16075            }
16076        }
16077
16078        if (mAlwaysFinishActivities) {
16079            // Need to do this on its own message because the stack may not
16080            // be in a consistent state at this point.
16081            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16082        }
16083
16084        if (allChanged) {
16085            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16086        }
16087
16088        if (mProcessStats.shouldWriteNowLocked(now)) {
16089            mHandler.post(new Runnable() {
16090                @Override public void run() {
16091                    synchronized (ActivityManagerService.this) {
16092                        mProcessStats.writeStateAsyncLocked();
16093                    }
16094                }
16095            });
16096        }
16097
16098        if (DEBUG_OOM_ADJ) {
16099            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16100        }
16101    }
16102
16103    final void trimApplications() {
16104        synchronized (this) {
16105            int i;
16106
16107            // First remove any unused application processes whose package
16108            // has been removed.
16109            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16110                final ProcessRecord app = mRemovedProcesses.get(i);
16111                if (app.activities.size() == 0
16112                        && app.curReceiver == null && app.services.size() == 0) {
16113                    Slog.i(
16114                        TAG, "Exiting empty application process "
16115                        + app.processName + " ("
16116                        + (app.thread != null ? app.thread.asBinder() : null)
16117                        + ")\n");
16118                    if (app.pid > 0 && app.pid != MY_PID) {
16119                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16120                                app.processName, app.setAdj, "empty");
16121                        app.killedByAm = true;
16122                        Process.killProcessQuiet(app.pid);
16123                    } else {
16124                        try {
16125                            app.thread.scheduleExit();
16126                        } catch (Exception e) {
16127                            // Ignore exceptions.
16128                        }
16129                    }
16130                    cleanUpApplicationRecordLocked(app, false, true, -1);
16131                    mRemovedProcesses.remove(i);
16132
16133                    if (app.persistent) {
16134                        if (app.persistent) {
16135                            addAppLocked(app.info, false);
16136                        }
16137                    }
16138                }
16139            }
16140
16141            // Now update the oom adj for all processes.
16142            updateOomAdjLocked();
16143        }
16144    }
16145
16146    /** This method sends the specified signal to each of the persistent apps */
16147    public void signalPersistentProcesses(int sig) throws RemoteException {
16148        if (sig != Process.SIGNAL_USR1) {
16149            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16150        }
16151
16152        synchronized (this) {
16153            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16154                    != PackageManager.PERMISSION_GRANTED) {
16155                throw new SecurityException("Requires permission "
16156                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16157            }
16158
16159            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16160                ProcessRecord r = mLruProcesses.get(i);
16161                if (r.thread != null && r.persistent) {
16162                    Process.sendSignal(r.pid, sig);
16163                }
16164            }
16165        }
16166    }
16167
16168    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16169        if (proc == null || proc == mProfileProc) {
16170            proc = mProfileProc;
16171            path = mProfileFile;
16172            profileType = mProfileType;
16173            clearProfilerLocked();
16174        }
16175        if (proc == null) {
16176            return;
16177        }
16178        try {
16179            proc.thread.profilerControl(false, path, null, profileType);
16180        } catch (RemoteException e) {
16181            throw new IllegalStateException("Process disappeared");
16182        }
16183    }
16184
16185    private void clearProfilerLocked() {
16186        if (mProfileFd != null) {
16187            try {
16188                mProfileFd.close();
16189            } catch (IOException e) {
16190            }
16191        }
16192        mProfileApp = null;
16193        mProfileProc = null;
16194        mProfileFile = null;
16195        mProfileType = 0;
16196        mAutoStopProfiler = false;
16197    }
16198
16199    public boolean profileControl(String process, int userId, boolean start,
16200            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16201
16202        try {
16203            synchronized (this) {
16204                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16205                // its own permission.
16206                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16207                        != PackageManager.PERMISSION_GRANTED) {
16208                    throw new SecurityException("Requires permission "
16209                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16210                }
16211
16212                if (start && fd == null) {
16213                    throw new IllegalArgumentException("null fd");
16214                }
16215
16216                ProcessRecord proc = null;
16217                if (process != null) {
16218                    proc = findProcessLocked(process, userId, "profileControl");
16219                }
16220
16221                if (start && (proc == null || proc.thread == null)) {
16222                    throw new IllegalArgumentException("Unknown process: " + process);
16223                }
16224
16225                if (start) {
16226                    stopProfilerLocked(null, null, 0);
16227                    setProfileApp(proc.info, proc.processName, path, fd, false);
16228                    mProfileProc = proc;
16229                    mProfileType = profileType;
16230                    try {
16231                        fd = fd.dup();
16232                    } catch (IOException e) {
16233                        fd = null;
16234                    }
16235                    proc.thread.profilerControl(start, path, fd, profileType);
16236                    fd = null;
16237                    mProfileFd = null;
16238                } else {
16239                    stopProfilerLocked(proc, path, profileType);
16240                    if (fd != null) {
16241                        try {
16242                            fd.close();
16243                        } catch (IOException e) {
16244                        }
16245                    }
16246                }
16247
16248                return true;
16249            }
16250        } catch (RemoteException e) {
16251            throw new IllegalStateException("Process disappeared");
16252        } finally {
16253            if (fd != null) {
16254                try {
16255                    fd.close();
16256                } catch (IOException e) {
16257                }
16258            }
16259        }
16260    }
16261
16262    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16263        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16264                userId, true, true, callName, null);
16265        ProcessRecord proc = null;
16266        try {
16267            int pid = Integer.parseInt(process);
16268            synchronized (mPidsSelfLocked) {
16269                proc = mPidsSelfLocked.get(pid);
16270            }
16271        } catch (NumberFormatException e) {
16272        }
16273
16274        if (proc == null) {
16275            ArrayMap<String, SparseArray<ProcessRecord>> all
16276                    = mProcessNames.getMap();
16277            SparseArray<ProcessRecord> procs = all.get(process);
16278            if (procs != null && procs.size() > 0) {
16279                proc = procs.valueAt(0);
16280                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16281                    for (int i=1; i<procs.size(); i++) {
16282                        ProcessRecord thisProc = procs.valueAt(i);
16283                        if (thisProc.userId == userId) {
16284                            proc = thisProc;
16285                            break;
16286                        }
16287                    }
16288                }
16289            }
16290        }
16291
16292        return proc;
16293    }
16294
16295    public boolean dumpHeap(String process, int userId, boolean managed,
16296            String path, ParcelFileDescriptor fd) throws RemoteException {
16297
16298        try {
16299            synchronized (this) {
16300                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16301                // its own permission (same as profileControl).
16302                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16303                        != PackageManager.PERMISSION_GRANTED) {
16304                    throw new SecurityException("Requires permission "
16305                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16306                }
16307
16308                if (fd == null) {
16309                    throw new IllegalArgumentException("null fd");
16310                }
16311
16312                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16313                if (proc == null || proc.thread == null) {
16314                    throw new IllegalArgumentException("Unknown process: " + process);
16315                }
16316
16317                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16318                if (!isDebuggable) {
16319                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16320                        throw new SecurityException("Process not debuggable: " + proc);
16321                    }
16322                }
16323
16324                proc.thread.dumpHeap(managed, path, fd);
16325                fd = null;
16326                return true;
16327            }
16328        } catch (RemoteException e) {
16329            throw new IllegalStateException("Process disappeared");
16330        } finally {
16331            if (fd != null) {
16332                try {
16333                    fd.close();
16334                } catch (IOException e) {
16335                }
16336            }
16337        }
16338    }
16339
16340    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16341    public void monitor() {
16342        synchronized (this) { }
16343    }
16344
16345    void onCoreSettingsChange(Bundle settings) {
16346        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16347            ProcessRecord processRecord = mLruProcesses.get(i);
16348            try {
16349                if (processRecord.thread != null) {
16350                    processRecord.thread.setCoreSettings(settings);
16351                }
16352            } catch (RemoteException re) {
16353                /* ignore */
16354            }
16355        }
16356    }
16357
16358    // Multi-user methods
16359
16360    /**
16361     * Start user, if its not already running, but don't bring it to foreground.
16362     */
16363    @Override
16364    public boolean startUserInBackground(final int userId) {
16365        return startUser(userId, /* foreground */ false);
16366    }
16367
16368    /**
16369     * Refreshes the list of users related to the current user when either a
16370     * user switch happens or when a new related user is started in the
16371     * background.
16372     */
16373    private void updateCurrentProfileIdsLocked() {
16374        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16375                mCurrentUserId, false /* enabledOnly */);
16376        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16377        for (int i = 0; i < currentProfileIds.length; i++) {
16378            currentProfileIds[i] = profiles.get(i).id;
16379        }
16380        mCurrentProfileIds = currentProfileIds;
16381    }
16382
16383    private Set getProfileIdsLocked(int userId) {
16384        Set userIds = new HashSet<Integer>();
16385        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16386                userId, false /* enabledOnly */);
16387        for (UserInfo user : profiles) {
16388            userIds.add(Integer.valueOf(user.id));
16389        }
16390        return userIds;
16391    }
16392
16393    @Override
16394    public boolean switchUser(final int userId) {
16395        return startUser(userId, /* foregound */ true);
16396    }
16397
16398    private boolean startUser(final int userId, boolean foreground) {
16399        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16400                != PackageManager.PERMISSION_GRANTED) {
16401            String msg = "Permission Denial: switchUser() from pid="
16402                    + Binder.getCallingPid()
16403                    + ", uid=" + Binder.getCallingUid()
16404                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16405            Slog.w(TAG, msg);
16406            throw new SecurityException(msg);
16407        }
16408
16409        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16410
16411        final long ident = Binder.clearCallingIdentity();
16412        try {
16413            synchronized (this) {
16414                final int oldUserId = mCurrentUserId;
16415                if (oldUserId == userId) {
16416                    return true;
16417                }
16418
16419                mStackSupervisor.setLockTaskModeLocked(null);
16420
16421                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16422                if (userInfo == null) {
16423                    Slog.w(TAG, "No user info for user #" + userId);
16424                    return false;
16425                }
16426
16427                if (foreground) {
16428                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16429                            R.anim.screen_user_enter);
16430                }
16431
16432                boolean needStart = false;
16433
16434                // If the user we are switching to is not currently started, then
16435                // we need to start it now.
16436                if (mStartedUsers.get(userId) == null) {
16437                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16438                    updateStartedUserArrayLocked();
16439                    needStart = true;
16440                }
16441
16442                final Integer userIdInt = Integer.valueOf(userId);
16443                mUserLru.remove(userIdInt);
16444                mUserLru.add(userIdInt);
16445
16446                if (foreground) {
16447                    mCurrentUserId = userId;
16448                    updateCurrentProfileIdsLocked();
16449                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16450                    // Once the internal notion of the active user has switched, we lock the device
16451                    // with the option to show the user switcher on the keyguard.
16452                    mWindowManager.lockNow(null);
16453                } else {
16454                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16455                    updateCurrentProfileIdsLocked();
16456                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16457                    mUserLru.remove(currentUserIdInt);
16458                    mUserLru.add(currentUserIdInt);
16459                }
16460
16461                final UserStartedState uss = mStartedUsers.get(userId);
16462
16463                // Make sure user is in the started state.  If it is currently
16464                // stopping, we need to knock that off.
16465                if (uss.mState == UserStartedState.STATE_STOPPING) {
16466                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16467                    // so we can just fairly silently bring the user back from
16468                    // the almost-dead.
16469                    uss.mState = UserStartedState.STATE_RUNNING;
16470                    updateStartedUserArrayLocked();
16471                    needStart = true;
16472                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16473                    // This means ACTION_SHUTDOWN has been sent, so we will
16474                    // need to treat this as a new boot of the user.
16475                    uss.mState = UserStartedState.STATE_BOOTING;
16476                    updateStartedUserArrayLocked();
16477                    needStart = true;
16478                }
16479
16480                if (uss.mState == UserStartedState.STATE_BOOTING) {
16481                    // Booting up a new user, need to tell system services about it.
16482                    // Note that this is on the same handler as scheduling of broadcasts,
16483                    // which is important because it needs to go first.
16484                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16485                }
16486
16487                if (foreground) {
16488                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16489                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16490                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16491                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16492                            oldUserId, userId, uss));
16493                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16494                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16495                }
16496
16497                if (needStart) {
16498                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16499                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16500                            | Intent.FLAG_RECEIVER_FOREGROUND);
16501                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16502                    broadcastIntentLocked(null, null, intent,
16503                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16504                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16505                }
16506
16507                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16508                    if (userId != 0) {
16509                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16510                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16511                        broadcastIntentLocked(null, null, intent, null,
16512                                new IIntentReceiver.Stub() {
16513                                    public void performReceive(Intent intent, int resultCode,
16514                                            String data, Bundle extras, boolean ordered,
16515                                            boolean sticky, int sendingUser) {
16516                                        userInitialized(uss, userId);
16517                                    }
16518                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16519                                true, false, MY_PID, Process.SYSTEM_UID,
16520                                userId);
16521                        uss.initializing = true;
16522                    } else {
16523                        getUserManagerLocked().makeInitialized(userInfo.id);
16524                    }
16525                }
16526
16527                if (foreground) {
16528                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16529                    if (homeInFront) {
16530                        startHomeActivityLocked(userId);
16531                    } else {
16532                        mStackSupervisor.resumeTopActivitiesLocked();
16533                    }
16534                    EventLogTags.writeAmSwitchUser(userId);
16535                    getUserManagerLocked().userForeground(userId);
16536                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16537                }
16538
16539                if (needStart) {
16540                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16541                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16542                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16543                    broadcastIntentLocked(null, null, intent,
16544                            null, new IIntentReceiver.Stub() {
16545                                @Override
16546                                public void performReceive(Intent intent, int resultCode, String data,
16547                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16548                                        throws RemoteException {
16549                                }
16550                            }, 0, null, null,
16551                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16552                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16553                }
16554            }
16555        } finally {
16556            Binder.restoreCallingIdentity(ident);
16557        }
16558
16559        return true;
16560    }
16561
16562    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16563        long ident = Binder.clearCallingIdentity();
16564        try {
16565            Intent intent;
16566            if (oldUserId >= 0) {
16567                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16568                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16569                        | Intent.FLAG_RECEIVER_FOREGROUND);
16570                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16571                broadcastIntentLocked(null, null, intent,
16572                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16573                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16574            }
16575            if (newUserId >= 0) {
16576                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16577                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16578                        | Intent.FLAG_RECEIVER_FOREGROUND);
16579                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16580                broadcastIntentLocked(null, null, intent,
16581                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16582                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16583                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16585                        | Intent.FLAG_RECEIVER_FOREGROUND);
16586                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16587                broadcastIntentLocked(null, null, intent,
16588                        null, null, 0, null, null,
16589                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16590                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16591            }
16592        } finally {
16593            Binder.restoreCallingIdentity(ident);
16594        }
16595    }
16596
16597    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16598            final int newUserId) {
16599        final int N = mUserSwitchObservers.beginBroadcast();
16600        if (N > 0) {
16601            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16602                int mCount = 0;
16603                @Override
16604                public void sendResult(Bundle data) throws RemoteException {
16605                    synchronized (ActivityManagerService.this) {
16606                        if (mCurUserSwitchCallback == this) {
16607                            mCount++;
16608                            if (mCount == N) {
16609                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16610                            }
16611                        }
16612                    }
16613                }
16614            };
16615            synchronized (this) {
16616                uss.switching = true;
16617                mCurUserSwitchCallback = callback;
16618            }
16619            for (int i=0; i<N; i++) {
16620                try {
16621                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16622                            newUserId, callback);
16623                } catch (RemoteException e) {
16624                }
16625            }
16626        } else {
16627            synchronized (this) {
16628                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16629            }
16630        }
16631        mUserSwitchObservers.finishBroadcast();
16632    }
16633
16634    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16635        synchronized (this) {
16636            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16637            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16638        }
16639    }
16640
16641    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16642        mCurUserSwitchCallback = null;
16643        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16644        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16645                oldUserId, newUserId, uss));
16646    }
16647
16648    void userInitialized(UserStartedState uss, int newUserId) {
16649        completeSwitchAndInitalize(uss, newUserId, true, false);
16650    }
16651
16652    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16653        completeSwitchAndInitalize(uss, newUserId, false, true);
16654    }
16655
16656    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16657            boolean clearInitializing, boolean clearSwitching) {
16658        boolean unfrozen = false;
16659        synchronized (this) {
16660            if (clearInitializing) {
16661                uss.initializing = false;
16662                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16663            }
16664            if (clearSwitching) {
16665                uss.switching = false;
16666            }
16667            if (!uss.switching && !uss.initializing) {
16668                mWindowManager.stopFreezingScreen();
16669                unfrozen = true;
16670            }
16671        }
16672        if (unfrozen) {
16673            final int N = mUserSwitchObservers.beginBroadcast();
16674            for (int i=0; i<N; i++) {
16675                try {
16676                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16677                } catch (RemoteException e) {
16678                }
16679            }
16680            mUserSwitchObservers.finishBroadcast();
16681        }
16682    }
16683
16684    void scheduleStartProfilesLocked() {
16685        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16686            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16687                    DateUtils.SECOND_IN_MILLIS);
16688        }
16689    }
16690
16691    void startProfilesLocked() {
16692        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16693        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16694                mCurrentUserId, false /* enabledOnly */);
16695        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16696        for (UserInfo user : profiles) {
16697            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16698                    && user.id != mCurrentUserId) {
16699                toStart.add(user);
16700            }
16701        }
16702        final int n = toStart.size();
16703        int i = 0;
16704        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16705            startUserInBackground(toStart.get(i).id);
16706        }
16707        if (i < n) {
16708            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16709        }
16710    }
16711
16712    void finishUserSwitch(UserStartedState uss) {
16713        synchronized (this) {
16714            if (uss.mState == UserStartedState.STATE_BOOTING
16715                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16716                uss.mState = UserStartedState.STATE_RUNNING;
16717                final int userId = uss.mHandle.getIdentifier();
16718                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16719                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16720                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16721                broadcastIntentLocked(null, null, intent,
16722                        null, null, 0, null, null,
16723                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16724                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16725            }
16726
16727            startProfilesLocked();
16728
16729            int num = mUserLru.size();
16730            int i = 0;
16731            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16732                Integer oldUserId = mUserLru.get(i);
16733                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16734                if (oldUss == null) {
16735                    // Shouldn't happen, but be sane if it does.
16736                    mUserLru.remove(i);
16737                    num--;
16738                    continue;
16739                }
16740                if (oldUss.mState == UserStartedState.STATE_STOPPING
16741                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16742                    // This user is already stopping, doesn't count.
16743                    num--;
16744                    i++;
16745                    continue;
16746                }
16747                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16748                    // Owner and current can't be stopped, but count as running.
16749                    i++;
16750                    continue;
16751                }
16752                // This is a user to be stopped.
16753                stopUserLocked(oldUserId, null);
16754                num--;
16755                i++;
16756            }
16757        }
16758    }
16759
16760    @Override
16761    public int stopUser(final int userId, final IStopUserCallback callback) {
16762        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16763                != PackageManager.PERMISSION_GRANTED) {
16764            String msg = "Permission Denial: switchUser() from pid="
16765                    + Binder.getCallingPid()
16766                    + ", uid=" + Binder.getCallingUid()
16767                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16768            Slog.w(TAG, msg);
16769            throw new SecurityException(msg);
16770        }
16771        if (userId <= 0) {
16772            throw new IllegalArgumentException("Can't stop primary user " + userId);
16773        }
16774        synchronized (this) {
16775            return stopUserLocked(userId, callback);
16776        }
16777    }
16778
16779    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16780        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16781        if (mCurrentUserId == userId) {
16782            return ActivityManager.USER_OP_IS_CURRENT;
16783        }
16784
16785        final UserStartedState uss = mStartedUsers.get(userId);
16786        if (uss == null) {
16787            // User is not started, nothing to do...  but we do need to
16788            // callback if requested.
16789            if (callback != null) {
16790                mHandler.post(new Runnable() {
16791                    @Override
16792                    public void run() {
16793                        try {
16794                            callback.userStopped(userId);
16795                        } catch (RemoteException e) {
16796                        }
16797                    }
16798                });
16799            }
16800            return ActivityManager.USER_OP_SUCCESS;
16801        }
16802
16803        if (callback != null) {
16804            uss.mStopCallbacks.add(callback);
16805        }
16806
16807        if (uss.mState != UserStartedState.STATE_STOPPING
16808                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16809            uss.mState = UserStartedState.STATE_STOPPING;
16810            updateStartedUserArrayLocked();
16811
16812            long ident = Binder.clearCallingIdentity();
16813            try {
16814                // We are going to broadcast ACTION_USER_STOPPING and then
16815                // once that is done send a final ACTION_SHUTDOWN and then
16816                // stop the user.
16817                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16818                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16819                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16820                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16821                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16822                // This is the result receiver for the final shutdown broadcast.
16823                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16824                    @Override
16825                    public void performReceive(Intent intent, int resultCode, String data,
16826                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16827                        finishUserStop(uss);
16828                    }
16829                };
16830                // This is the result receiver for the initial stopping broadcast.
16831                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16832                    @Override
16833                    public void performReceive(Intent intent, int resultCode, String data,
16834                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16835                        // On to the next.
16836                        synchronized (ActivityManagerService.this) {
16837                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16838                                // Whoops, we are being started back up.  Abort, abort!
16839                                return;
16840                            }
16841                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16842                        }
16843                        mSystemServiceManager.stopUser(userId);
16844                        broadcastIntentLocked(null, null, shutdownIntent,
16845                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16846                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16847                    }
16848                };
16849                // Kick things off.
16850                broadcastIntentLocked(null, null, stoppingIntent,
16851                        null, stoppingReceiver, 0, null, null,
16852                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16853                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16854            } finally {
16855                Binder.restoreCallingIdentity(ident);
16856            }
16857        }
16858
16859        return ActivityManager.USER_OP_SUCCESS;
16860    }
16861
16862    void finishUserStop(UserStartedState uss) {
16863        final int userId = uss.mHandle.getIdentifier();
16864        boolean stopped;
16865        ArrayList<IStopUserCallback> callbacks;
16866        synchronized (this) {
16867            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16868            if (mStartedUsers.get(userId) != uss) {
16869                stopped = false;
16870            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16871                stopped = false;
16872            } else {
16873                stopped = true;
16874                // User can no longer run.
16875                mStartedUsers.remove(userId);
16876                mUserLru.remove(Integer.valueOf(userId));
16877                updateStartedUserArrayLocked();
16878
16879                // Clean up all state and processes associated with the user.
16880                // Kill all the processes for the user.
16881                forceStopUserLocked(userId, "finish user");
16882            }
16883        }
16884
16885        for (int i=0; i<callbacks.size(); i++) {
16886            try {
16887                if (stopped) callbacks.get(i).userStopped(userId);
16888                else callbacks.get(i).userStopAborted(userId);
16889            } catch (RemoteException e) {
16890            }
16891        }
16892
16893        if (stopped) {
16894            mSystemServiceManager.cleanupUser(userId);
16895            synchronized (this) {
16896                mStackSupervisor.removeUserLocked(userId);
16897            }
16898        }
16899    }
16900
16901    @Override
16902    public UserInfo getCurrentUser() {
16903        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16904                != PackageManager.PERMISSION_GRANTED) && (
16905                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16906                != PackageManager.PERMISSION_GRANTED)) {
16907            String msg = "Permission Denial: getCurrentUser() from pid="
16908                    + Binder.getCallingPid()
16909                    + ", uid=" + Binder.getCallingUid()
16910                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16911            Slog.w(TAG, msg);
16912            throw new SecurityException(msg);
16913        }
16914        synchronized (this) {
16915            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16916        }
16917    }
16918
16919    int getCurrentUserIdLocked() {
16920        return mCurrentUserId;
16921    }
16922
16923    @Override
16924    public boolean isUserRunning(int userId, boolean orStopped) {
16925        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16926                != PackageManager.PERMISSION_GRANTED) {
16927            String msg = "Permission Denial: isUserRunning() from pid="
16928                    + Binder.getCallingPid()
16929                    + ", uid=" + Binder.getCallingUid()
16930                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16931            Slog.w(TAG, msg);
16932            throw new SecurityException(msg);
16933        }
16934        synchronized (this) {
16935            return isUserRunningLocked(userId, orStopped);
16936        }
16937    }
16938
16939    boolean isUserRunningLocked(int userId, boolean orStopped) {
16940        UserStartedState state = mStartedUsers.get(userId);
16941        if (state == null) {
16942            return false;
16943        }
16944        if (orStopped) {
16945            return true;
16946        }
16947        return state.mState != UserStartedState.STATE_STOPPING
16948                && state.mState != UserStartedState.STATE_SHUTDOWN;
16949    }
16950
16951    @Override
16952    public int[] getRunningUserIds() {
16953        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16954                != PackageManager.PERMISSION_GRANTED) {
16955            String msg = "Permission Denial: isUserRunning() from pid="
16956                    + Binder.getCallingPid()
16957                    + ", uid=" + Binder.getCallingUid()
16958                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16959            Slog.w(TAG, msg);
16960            throw new SecurityException(msg);
16961        }
16962        synchronized (this) {
16963            return mStartedUserArray;
16964        }
16965    }
16966
16967    private void updateStartedUserArrayLocked() {
16968        int num = 0;
16969        for (int i=0; i<mStartedUsers.size();  i++) {
16970            UserStartedState uss = mStartedUsers.valueAt(i);
16971            // This list does not include stopping users.
16972            if (uss.mState != UserStartedState.STATE_STOPPING
16973                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16974                num++;
16975            }
16976        }
16977        mStartedUserArray = new int[num];
16978        num = 0;
16979        for (int i=0; i<mStartedUsers.size();  i++) {
16980            UserStartedState uss = mStartedUsers.valueAt(i);
16981            if (uss.mState != UserStartedState.STATE_STOPPING
16982                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16983                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16984                num++;
16985            }
16986        }
16987    }
16988
16989    @Override
16990    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16991        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16992                != PackageManager.PERMISSION_GRANTED) {
16993            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16994                    + Binder.getCallingPid()
16995                    + ", uid=" + Binder.getCallingUid()
16996                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16997            Slog.w(TAG, msg);
16998            throw new SecurityException(msg);
16999        }
17000
17001        mUserSwitchObservers.register(observer);
17002    }
17003
17004    @Override
17005    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17006        mUserSwitchObservers.unregister(observer);
17007    }
17008
17009    private boolean userExists(int userId) {
17010        if (userId == 0) {
17011            return true;
17012        }
17013        UserManagerService ums = getUserManagerLocked();
17014        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17015    }
17016
17017    int[] getUsersLocked() {
17018        UserManagerService ums = getUserManagerLocked();
17019        return ums != null ? ums.getUserIds() : new int[] { 0 };
17020    }
17021
17022    UserManagerService getUserManagerLocked() {
17023        if (mUserManager == null) {
17024            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17025            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17026        }
17027        return mUserManager;
17028    }
17029
17030    private int applyUserId(int uid, int userId) {
17031        return UserHandle.getUid(userId, uid);
17032    }
17033
17034    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17035        if (info == null) return null;
17036        ApplicationInfo newInfo = new ApplicationInfo(info);
17037        newInfo.uid = applyUserId(info.uid, userId);
17038        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17039                + info.packageName;
17040        return newInfo;
17041    }
17042
17043    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17044        if (aInfo == null
17045                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17046            return aInfo;
17047        }
17048
17049        ActivityInfo info = new ActivityInfo(aInfo);
17050        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17051        return info;
17052    }
17053
17054    private final class LocalService extends ActivityManagerInternal {
17055        @Override
17056        public void goingToSleep() {
17057            ActivityManagerService.this.goingToSleep();
17058        }
17059
17060        @Override
17061        public void wakingUp() {
17062            ActivityManagerService.this.wakingUp();
17063        }
17064    }
17065}
17066