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