ActivityManagerService.java revision 5df281a570555ee132a12a4aac9aec96e8618270
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.ProxyInfo;
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 increase 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                ProxyInfo proxy = (ProxyInfo)msg.obj;
1327                String host = "";
1328                String port = "";
1329                String exclList = "";
1330                String pacFileUrl = "";
1331                if (proxy != null) {
1332                    host = proxy.getHost();
1333                    port = Integer.toString(proxy.getPort());
1334                    exclList = proxy.getExclusionListAsString();
1335                    if (proxy.getPacFileUrl() != null) {
1336                        pacFileUrl = proxy.getPacFileUrl().toString();
1337                    }
1338                }
1339                synchronized (ActivityManagerService.this) {
1340                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1341                        ProcessRecord r = mLruProcesses.get(i);
1342                        if (r.thread != null) {
1343                            try {
1344                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1345                            } catch (RemoteException ex) {
1346                                Slog.w(TAG, "Failed to update http proxy for: " +
1347                                        r.info.processName);
1348                            }
1349                        }
1350                    }
1351                }
1352            } break;
1353            case SHOW_UID_ERROR_MSG: {
1354                String title = "System UIDs Inconsistent";
1355                String text = "UIDs on the system are inconsistent, you need to wipe your"
1356                        + " data partition or your device will be unstable.";
1357                Log.e(TAG, title + ": " + text);
1358                if (mShowDialogs) {
1359                    // XXX This is a temporary dialog, no need to localize.
1360                    AlertDialog d = new BaseErrorDialog(mContext);
1361                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1362                    d.setCancelable(false);
1363                    d.setTitle(title);
1364                    d.setMessage(text);
1365                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1366                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1367                    mUidAlert = d;
1368                    d.show();
1369                }
1370            } break;
1371            case IM_FEELING_LUCKY_MSG: {
1372                if (mUidAlert != null) {
1373                    mUidAlert.dismiss();
1374                    mUidAlert = null;
1375                }
1376            } break;
1377            case PROC_START_TIMEOUT_MSG: {
1378                if (mDidDexOpt) {
1379                    mDidDexOpt = false;
1380                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1381                    nmsg.obj = msg.obj;
1382                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1383                    return;
1384                }
1385                ProcessRecord app = (ProcessRecord)msg.obj;
1386                synchronized (ActivityManagerService.this) {
1387                    processStartTimedOutLocked(app);
1388                }
1389            } break;
1390            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    doPendingActivityLaunchesLocked(true);
1393                }
1394            } break;
1395            case KILL_APPLICATION_MSG: {
1396                synchronized (ActivityManagerService.this) {
1397                    int appid = msg.arg1;
1398                    boolean restart = (msg.arg2 == 1);
1399                    Bundle bundle = (Bundle)msg.obj;
1400                    String pkg = bundle.getString("pkg");
1401                    String reason = bundle.getString("reason");
1402                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1403                            false, UserHandle.USER_ALL, reason);
1404                }
1405            } break;
1406            case FINALIZE_PENDING_INTENT_MSG: {
1407                ((PendingIntentRecord)msg.obj).completeFinalize();
1408            } break;
1409            case POST_HEAVY_NOTIFICATION_MSG: {
1410                INotificationManager inm = NotificationManager.getService();
1411                if (inm == null) {
1412                    return;
1413                }
1414
1415                ActivityRecord root = (ActivityRecord)msg.obj;
1416                ProcessRecord process = root.app;
1417                if (process == null) {
1418                    return;
1419                }
1420
1421                try {
1422                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1423                    String text = mContext.getString(R.string.heavy_weight_notification,
1424                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1425                    Notification notification = new Notification();
1426                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1427                    notification.when = 0;
1428                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1429                    notification.tickerText = text;
1430                    notification.defaults = 0; // please be quiet
1431                    notification.sound = null;
1432                    notification.vibrate = null;
1433                    notification.setLatestEventInfo(context, text,
1434                            mContext.getText(R.string.heavy_weight_notification_detail),
1435                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1436                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1437                                    new UserHandle(root.userId)));
1438
1439                    try {
1440                        int[] outId = new int[1];
1441                        inm.enqueueNotificationWithTag("android", "android", null,
1442                                R.string.heavy_weight_notification,
1443                                notification, outId, root.userId);
1444                    } catch (RuntimeException e) {
1445                        Slog.w(ActivityManagerService.TAG,
1446                                "Error showing notification for heavy-weight app", e);
1447                    } catch (RemoteException e) {
1448                    }
1449                } catch (NameNotFoundException e) {
1450                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1451                }
1452            } break;
1453            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1454                INotificationManager inm = NotificationManager.getService();
1455                if (inm == null) {
1456                    return;
1457                }
1458                try {
1459                    inm.cancelNotificationWithTag("android", null,
1460                            R.string.heavy_weight_notification,  msg.arg1);
1461                } catch (RuntimeException e) {
1462                    Slog.w(ActivityManagerService.TAG,
1463                            "Error canceling notification for service", e);
1464                } catch (RemoteException e) {
1465                }
1466            } break;
1467            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1468                synchronized (ActivityManagerService.this) {
1469                    checkExcessivePowerUsageLocked(true);
1470                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1471                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1472                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1473                }
1474            } break;
1475            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1476                synchronized (ActivityManagerService.this) {
1477                    ActivityRecord ar = (ActivityRecord)msg.obj;
1478                    if (mCompatModeDialog != null) {
1479                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1480                                ar.info.applicationInfo.packageName)) {
1481                            return;
1482                        }
1483                        mCompatModeDialog.dismiss();
1484                        mCompatModeDialog = null;
1485                    }
1486                    if (ar != null && false) {
1487                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1488                                ar.packageName)) {
1489                            int mode = mCompatModePackages.computeCompatModeLocked(
1490                                    ar.info.applicationInfo);
1491                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1492                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1493                                mCompatModeDialog = new CompatModeDialog(
1494                                        ActivityManagerService.this, mContext,
1495                                        ar.info.applicationInfo);
1496                                mCompatModeDialog.show();
1497                            }
1498                        }
1499                    }
1500                }
1501                break;
1502            }
1503            case DISPATCH_PROCESSES_CHANGED: {
1504                dispatchProcessesChanged();
1505                break;
1506            }
1507            case DISPATCH_PROCESS_DIED: {
1508                final int pid = msg.arg1;
1509                final int uid = msg.arg2;
1510                dispatchProcessDied(pid, uid);
1511                break;
1512            }
1513            case REPORT_MEM_USAGE_MSG: {
1514                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1515                Thread thread = new Thread() {
1516                    @Override public void run() {
1517                        final SparseArray<ProcessMemInfo> infoMap
1518                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1519                        for (int i=0, N=memInfos.size(); i<N; i++) {
1520                            ProcessMemInfo mi = memInfos.get(i);
1521                            infoMap.put(mi.pid, mi);
1522                        }
1523                        updateCpuStatsNow();
1524                        synchronized (mProcessCpuThread) {
1525                            final int N = mProcessCpuTracker.countStats();
1526                            for (int i=0; i<N; i++) {
1527                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1528                                if (st.vsize > 0) {
1529                                    long pss = Debug.getPss(st.pid, null);
1530                                    if (pss > 0) {
1531                                        if (infoMap.indexOfKey(st.pid) < 0) {
1532                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1533                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1534                                            mi.pss = pss;
1535                                            memInfos.add(mi);
1536                                        }
1537                                    }
1538                                }
1539                            }
1540                        }
1541
1542                        long totalPss = 0;
1543                        for (int i=0, N=memInfos.size(); i<N; i++) {
1544                            ProcessMemInfo mi = memInfos.get(i);
1545                            if (mi.pss == 0) {
1546                                mi.pss = Debug.getPss(mi.pid, null);
1547                            }
1548                            totalPss += mi.pss;
1549                        }
1550                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1551                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1552                                if (lhs.oomAdj != rhs.oomAdj) {
1553                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1554                                }
1555                                if (lhs.pss != rhs.pss) {
1556                                    return lhs.pss < rhs.pss ? 1 : -1;
1557                                }
1558                                return 0;
1559                            }
1560                        });
1561
1562                        StringBuilder tag = new StringBuilder(128);
1563                        StringBuilder stack = new StringBuilder(128);
1564                        tag.append("Low on memory -- ");
1565                        appendMemBucket(tag, totalPss, "total", false);
1566                        appendMemBucket(stack, totalPss, "total", true);
1567
1568                        StringBuilder logBuilder = new StringBuilder(1024);
1569                        logBuilder.append("Low on memory:\n");
1570
1571                        boolean firstLine = true;
1572                        int lastOomAdj = Integer.MIN_VALUE;
1573                        for (int i=0, N=memInfos.size(); i<N; i++) {
1574                            ProcessMemInfo mi = memInfos.get(i);
1575
1576                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1577                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1578                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1579                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1580                                if (lastOomAdj != mi.oomAdj) {
1581                                    lastOomAdj = mi.oomAdj;
1582                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1583                                        tag.append(" / ");
1584                                    }
1585                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1586                                        if (firstLine) {
1587                                            stack.append(":");
1588                                            firstLine = false;
1589                                        }
1590                                        stack.append("\n\t at ");
1591                                    } else {
1592                                        stack.append("$");
1593                                    }
1594                                } else {
1595                                    tag.append(" ");
1596                                    stack.append("$");
1597                                }
1598                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1599                                    appendMemBucket(tag, mi.pss, mi.name, false);
1600                                }
1601                                appendMemBucket(stack, mi.pss, mi.name, true);
1602                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1603                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1604                                    stack.append("(");
1605                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1606                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1607                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1608                                            stack.append(":");
1609                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1610                                        }
1611                                    }
1612                                    stack.append(")");
1613                                }
1614                            }
1615
1616                            logBuilder.append("  ");
1617                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1618                            logBuilder.append(' ');
1619                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1620                            logBuilder.append(' ');
1621                            ProcessList.appendRamKb(logBuilder, mi.pss);
1622                            logBuilder.append(" kB: ");
1623                            logBuilder.append(mi.name);
1624                            logBuilder.append(" (");
1625                            logBuilder.append(mi.pid);
1626                            logBuilder.append(") ");
1627                            logBuilder.append(mi.adjType);
1628                            logBuilder.append('\n');
1629                            if (mi.adjReason != null) {
1630                                logBuilder.append("                      ");
1631                                logBuilder.append(mi.adjReason);
1632                                logBuilder.append('\n');
1633                            }
1634                        }
1635
1636                        logBuilder.append("           ");
1637                        ProcessList.appendRamKb(logBuilder, totalPss);
1638                        logBuilder.append(" kB: TOTAL\n");
1639
1640                        long[] infos = new long[Debug.MEMINFO_COUNT];
1641                        Debug.getMemInfo(infos);
1642                        logBuilder.append("  MemInfo: ");
1643                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1644                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1646                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1647                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1648                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1649                            logBuilder.append("  ZRAM: ");
1650                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1651                            logBuilder.append(" kB RAM, ");
1652                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1653                            logBuilder.append(" kB swap total, ");
1654                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1655                            logBuilder.append(" kB swap free\n");
1656                        }
1657                        Slog.i(TAG, logBuilder.toString());
1658
1659                        StringBuilder dropBuilder = new StringBuilder(1024);
1660                        /*
1661                        StringWriter oomSw = new StringWriter();
1662                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1663                        StringWriter catSw = new StringWriter();
1664                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1665                        String[] emptyArgs = new String[] { };
1666                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1667                        oomPw.flush();
1668                        String oomString = oomSw.toString();
1669                        */
1670                        dropBuilder.append(stack);
1671                        dropBuilder.append('\n');
1672                        dropBuilder.append('\n');
1673                        dropBuilder.append(logBuilder);
1674                        dropBuilder.append('\n');
1675                        /*
1676                        dropBuilder.append(oomString);
1677                        dropBuilder.append('\n');
1678                        */
1679                        StringWriter catSw = new StringWriter();
1680                        synchronized (ActivityManagerService.this) {
1681                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1682                            String[] emptyArgs = new String[] { };
1683                            catPw.println();
1684                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1685                            catPw.println();
1686                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1687                                    false, false, null);
1688                            catPw.println();
1689                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1690                            catPw.flush();
1691                        }
1692                        dropBuilder.append(catSw.toString());
1693                        addErrorToDropBox("lowmem", null, "system_server", null,
1694                                null, tag.toString(), dropBuilder.toString(), null, null);
1695                        //Slog.i(TAG, "Sent to dropbox:");
1696                        //Slog.i(TAG, dropBuilder.toString());
1697                        synchronized (ActivityManagerService.this) {
1698                            long now = SystemClock.uptimeMillis();
1699                            if (mLastMemUsageReportTime < now) {
1700                                mLastMemUsageReportTime = now;
1701                            }
1702                        }
1703                    }
1704                };
1705                thread.start();
1706                break;
1707            }
1708            case REPORT_USER_SWITCH_MSG: {
1709                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1710                break;
1711            }
1712            case CONTINUE_USER_SWITCH_MSG: {
1713                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1714                break;
1715            }
1716            case USER_SWITCH_TIMEOUT_MSG: {
1717                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1718                break;
1719            }
1720            case IMMERSIVE_MODE_LOCK_MSG: {
1721                final boolean nextState = (msg.arg1 != 0);
1722                if (mUpdateLock.isHeld() != nextState) {
1723                    if (DEBUG_IMMERSIVE) {
1724                        final ActivityRecord r = (ActivityRecord) msg.obj;
1725                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1726                    }
1727                    if (nextState) {
1728                        mUpdateLock.acquire();
1729                    } else {
1730                        mUpdateLock.release();
1731                    }
1732                }
1733                break;
1734            }
1735            case PERSIST_URI_GRANTS_MSG: {
1736                writeGrantedUriPermissions();
1737                break;
1738            }
1739            case REQUEST_ALL_PSS_MSG: {
1740                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1741                break;
1742            }
1743            case START_PROFILES_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    startProfilesLocked();
1746                }
1747                break;
1748            }
1749            case UPDATE_TIME: {
1750                synchronized (ActivityManagerService.this) {
1751                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1752                        ProcessRecord r = mLruProcesses.get(i);
1753                        if (r.thread != null) {
1754                            try {
1755                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1756                            } catch (RemoteException ex) {
1757                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1758                            }
1759                        }
1760                    }
1761                }
1762                break;
1763            }
1764            case SYSTEM_USER_START_MSG: {
1765                mSystemServiceManager.startUser(msg.arg1);
1766                break;
1767            }
1768            case SYSTEM_USER_CURRENT_MSG: {
1769                mSystemServiceManager.switchUser(msg.arg1);
1770                break;
1771            }
1772            }
1773        }
1774    };
1775
1776    static final int COLLECT_PSS_BG_MSG = 1;
1777
1778    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1779        @Override
1780        public void handleMessage(Message msg) {
1781            switch (msg.what) {
1782            case COLLECT_PSS_BG_MSG: {
1783                int i=0, num=0;
1784                long start = SystemClock.uptimeMillis();
1785                long[] tmp = new long[1];
1786                do {
1787                    ProcessRecord proc;
1788                    int procState;
1789                    int pid;
1790                    synchronized (ActivityManagerService.this) {
1791                        if (i >= mPendingPssProcesses.size()) {
1792                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1793                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1794                            mPendingPssProcesses.clear();
1795                            return;
1796                        }
1797                        proc = mPendingPssProcesses.get(i);
1798                        procState = proc.pssProcState;
1799                        if (proc.thread != null && procState == proc.setProcState) {
1800                            pid = proc.pid;
1801                        } else {
1802                            proc = null;
1803                            pid = 0;
1804                        }
1805                        i++;
1806                    }
1807                    if (proc != null) {
1808                        long pss = Debug.getPss(pid, tmp);
1809                        synchronized (ActivityManagerService.this) {
1810                            if (proc.thread != null && proc.setProcState == procState
1811                                    && proc.pid == pid) {
1812                                num++;
1813                                proc.lastPssTime = SystemClock.uptimeMillis();
1814                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1815                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1816                                        + ": " + pss + " lastPss=" + proc.lastPss
1817                                        + " state=" + ProcessList.makeProcStateString(procState));
1818                                if (proc.initialIdlePss == 0) {
1819                                    proc.initialIdlePss = pss;
1820                                }
1821                                proc.lastPss = pss;
1822                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1823                                    proc.lastCachedPss = pss;
1824                                }
1825                            }
1826                        }
1827                    }
1828                } while (true);
1829            }
1830            }
1831        }
1832    };
1833
1834    /**
1835     * Monitor for package changes and update our internal state.
1836     */
1837    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1838        @Override
1839        public void onPackageRemoved(String packageName, int uid) {
1840            // Remove all tasks with activities in the specified package from the list of recent tasks
1841            synchronized (ActivityManagerService.this) {
1842                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1843                    TaskRecord tr = mRecentTasks.get(i);
1844                    ComponentName cn = tr.intent.getComponent();
1845                    if (cn != null && cn.getPackageName().equals(packageName)) {
1846                        // If the package name matches, remove the task and kill the process
1847                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1848                    }
1849                }
1850            }
1851        }
1852
1853        @Override
1854        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1855            final PackageManager pm = mContext.getPackageManager();
1856            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1857                    new ArrayList<Pair<Intent, Integer>>();
1858            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1859            // Copy the list of recent tasks so that we don't hold onto the lock on
1860            // ActivityManagerService for long periods while checking if components exist.
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1865                }
1866            }
1867            // Check the recent tasks and filter out all tasks with components that no longer exist.
1868            Intent tmpI = new Intent();
1869            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1870                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1871                ComponentName cn = p.first.getComponent();
1872                if (cn != null && cn.getPackageName().equals(packageName)) {
1873                    try {
1874                        // Add the task to the list to remove if the component no longer exists
1875                        tmpI.setComponent(cn);
1876                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1877                            tasksToRemove.add(p.second);
1878                        }
1879                    } catch (Exception e) {}
1880                }
1881            }
1882            // Prune all the tasks with removed components from the list of recent tasks
1883            synchronized (ActivityManagerService.this) {
1884                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1885                    // Remove the task but don't kill the process (since other components in that
1886                    // package may still be running and in the background)
1887                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1888                }
1889            }
1890            return true;
1891        }
1892
1893        @Override
1894        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1895            // Force stop the specified packages
1896            if (packages != null) {
1897                for (String pkg : packages) {
1898                    synchronized (ActivityManagerService.this) {
1899                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1900                                "finished booting")) {
1901                            return true;
1902                        }
1903                    }
1904                }
1905            }
1906            return false;
1907        }
1908    };
1909
1910    public void setSystemProcess() {
1911        try {
1912            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1913            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1914            ServiceManager.addService("meminfo", new MemBinder(this));
1915            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1916            ServiceManager.addService("dbinfo", new DbBinder(this));
1917            if (MONITOR_CPU_USAGE) {
1918                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1919            }
1920            ServiceManager.addService("permission", new PermissionController(this));
1921
1922            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1923                    "android", STOCK_PM_FLAGS);
1924            mSystemThread.installSystemApplicationInfo(info);
1925
1926            synchronized (this) {
1927                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1928                app.persistent = true;
1929                app.pid = MY_PID;
1930                app.maxAdj = ProcessList.SYSTEM_ADJ;
1931                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1932                mProcessNames.put(app.processName, app.uid, app);
1933                synchronized (mPidsSelfLocked) {
1934                    mPidsSelfLocked.put(app.pid, app);
1935                }
1936                updateLruProcessLocked(app, false, null);
1937                updateOomAdjLocked();
1938            }
1939        } catch (PackageManager.NameNotFoundException e) {
1940            throw new RuntimeException(
1941                    "Unable to find android system package", e);
1942        }
1943    }
1944
1945    public void setWindowManager(WindowManagerService wm) {
1946        mWindowManager = wm;
1947        mStackSupervisor.setWindowManager(wm);
1948    }
1949
1950    public void startObservingNativeCrashes() {
1951        final NativeCrashListener ncl = new NativeCrashListener(this);
1952        ncl.start();
1953    }
1954
1955    public IAppOpsService getAppOpsService() {
1956        return mAppOpsService;
1957    }
1958
1959    static class MemBinder extends Binder {
1960        ActivityManagerService mActivityManagerService;
1961        MemBinder(ActivityManagerService activityManagerService) {
1962            mActivityManagerService = activityManagerService;
1963        }
1964
1965        @Override
1966        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1967            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1968                    != PackageManager.PERMISSION_GRANTED) {
1969                pw.println("Permission Denial: can't dump meminfo from from pid="
1970                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1971                        + " without permission " + android.Manifest.permission.DUMP);
1972                return;
1973            }
1974
1975            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1976        }
1977    }
1978
1979    static class GraphicsBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        GraphicsBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1996        }
1997    }
1998
1999    static class DbBinder extends Binder {
2000        ActivityManagerService mActivityManagerService;
2001        DbBinder(ActivityManagerService activityManagerService) {
2002            mActivityManagerService = activityManagerService;
2003        }
2004
2005        @Override
2006        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2007            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2008                    != PackageManager.PERMISSION_GRANTED) {
2009                pw.println("Permission Denial: can't dump dbinfo from from pid="
2010                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2011                        + " without permission " + android.Manifest.permission.DUMP);
2012                return;
2013            }
2014
2015            mActivityManagerService.dumpDbInfo(fd, pw, args);
2016        }
2017    }
2018
2019    static class CpuBinder extends Binder {
2020        ActivityManagerService mActivityManagerService;
2021        CpuBinder(ActivityManagerService activityManagerService) {
2022            mActivityManagerService = activityManagerService;
2023        }
2024
2025        @Override
2026        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2027            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2028                    != PackageManager.PERMISSION_GRANTED) {
2029                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2030                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2031                        + " without permission " + android.Manifest.permission.DUMP);
2032                return;
2033            }
2034
2035            synchronized (mActivityManagerService.mProcessCpuThread) {
2036                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2037                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2038                        SystemClock.uptimeMillis()));
2039            }
2040        }
2041    }
2042
2043    public static final class Lifecycle extends SystemService {
2044        private final ActivityManagerService mService;
2045
2046        public Lifecycle(Context context) {
2047            super(context);
2048            mService = new ActivityManagerService(context);
2049        }
2050
2051        @Override
2052        public void onStart() {
2053            mService.start();
2054        }
2055
2056        public ActivityManagerService getService() {
2057            return mService;
2058        }
2059    }
2060
2061    // Note: This method is invoked on the main thread but may need to attach various
2062    // handlers to other threads.  So take care to be explicit about the looper.
2063    public ActivityManagerService(Context systemContext) {
2064        mContext = systemContext;
2065        mFactoryTest = FactoryTest.getMode();
2066        mSystemThread = ActivityThread.currentActivityThread();
2067
2068        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2069
2070        mHandlerThread = new ServiceThread(TAG,
2071                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2072        mHandlerThread.start();
2073        mHandler = new MainHandler(mHandlerThread.getLooper());
2074
2075        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2076                "foreground", BROADCAST_FG_TIMEOUT, false);
2077        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2078                "background", BROADCAST_BG_TIMEOUT, true);
2079        mBroadcastQueues[0] = mFgBroadcastQueue;
2080        mBroadcastQueues[1] = mBgBroadcastQueue;
2081
2082        mServices = new ActiveServices(this);
2083        mProviderMap = new ProviderMap(this);
2084
2085        // TODO: Move creation of battery stats service outside of activity manager service.
2086        File dataDir = Environment.getDataDirectory();
2087        File systemDir = new File(dataDir, "system");
2088        systemDir.mkdirs();
2089        mBatteryStatsService = new BatteryStatsService(new File(
2090                systemDir, "batterystats.bin").toString(), mHandler);
2091        mBatteryStatsService.getActiveStatistics().readLocked();
2092        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2093        mOnBattery = DEBUG_POWER ? true
2094                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2095        mBatteryStatsService.getActiveStatistics().setCallback(this);
2096
2097        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2098
2099        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2100        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2101
2102        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2103
2104        // User 0 is the first and only user that runs at boot.
2105        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2106        mUserLru.add(Integer.valueOf(0));
2107        updateStartedUserArrayLocked();
2108
2109        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2110            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2111
2112        mConfiguration.setToDefaults();
2113        mConfiguration.setLocale(Locale.getDefault());
2114
2115        mConfigurationSeq = mConfiguration.seq = 1;
2116        mProcessCpuTracker.init();
2117
2118        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2119        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2120        mStackSupervisor = new ActivityStackSupervisor(this);
2121
2122        mProcessCpuThread = new Thread("CpuTracker") {
2123            @Override
2124            public void run() {
2125                while (true) {
2126                    try {
2127                        try {
2128                            synchronized(this) {
2129                                final long now = SystemClock.uptimeMillis();
2130                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2131                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2132                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2133                                //        + ", write delay=" + nextWriteDelay);
2134                                if (nextWriteDelay < nextCpuDelay) {
2135                                    nextCpuDelay = nextWriteDelay;
2136                                }
2137                                if (nextCpuDelay > 0) {
2138                                    mProcessCpuMutexFree.set(true);
2139                                    this.wait(nextCpuDelay);
2140                                }
2141                            }
2142                        } catch (InterruptedException e) {
2143                        }
2144                        updateCpuStatsNow();
2145                    } catch (Exception e) {
2146                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2147                    }
2148                }
2149            }
2150        };
2151
2152        Watchdog.getInstance().addMonitor(this);
2153        Watchdog.getInstance().addThread(mHandler);
2154    }
2155
2156    public void setSystemServiceManager(SystemServiceManager mgr) {
2157        mSystemServiceManager = mgr;
2158    }
2159
2160    private void start() {
2161        mProcessCpuThread.start();
2162
2163        mBatteryStatsService.publish(mContext);
2164        mUsageStatsService.publish(mContext);
2165        mAppOpsService.publish(mContext);
2166
2167        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2168    }
2169
2170    @Override
2171    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2172            throws RemoteException {
2173        if (code == SYSPROPS_TRANSACTION) {
2174            // We need to tell all apps about the system property change.
2175            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2176            synchronized(this) {
2177                final int NP = mProcessNames.getMap().size();
2178                for (int ip=0; ip<NP; ip++) {
2179                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2180                    final int NA = apps.size();
2181                    for (int ia=0; ia<NA; ia++) {
2182                        ProcessRecord app = apps.valueAt(ia);
2183                        if (app.thread != null) {
2184                            procs.add(app.thread.asBinder());
2185                        }
2186                    }
2187                }
2188            }
2189
2190            int N = procs.size();
2191            for (int i=0; i<N; i++) {
2192                Parcel data2 = Parcel.obtain();
2193                try {
2194                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2195                } catch (RemoteException e) {
2196                }
2197                data2.recycle();
2198            }
2199        }
2200        try {
2201            return super.onTransact(code, data, reply, flags);
2202        } catch (RuntimeException e) {
2203            // The activity manager only throws security exceptions, so let's
2204            // log all others.
2205            if (!(e instanceof SecurityException)) {
2206                Slog.wtf(TAG, "Activity Manager Crash", e);
2207            }
2208            throw e;
2209        }
2210    }
2211
2212    void updateCpuStats() {
2213        final long now = SystemClock.uptimeMillis();
2214        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2215            return;
2216        }
2217        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2218            synchronized (mProcessCpuThread) {
2219                mProcessCpuThread.notify();
2220            }
2221        }
2222    }
2223
2224    void updateCpuStatsNow() {
2225        synchronized (mProcessCpuThread) {
2226            mProcessCpuMutexFree.set(false);
2227            final long now = SystemClock.uptimeMillis();
2228            boolean haveNewCpuStats = false;
2229
2230            if (MONITOR_CPU_USAGE &&
2231                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2232                mLastCpuTime.set(now);
2233                haveNewCpuStats = true;
2234                mProcessCpuTracker.update();
2235                //Slog.i(TAG, mProcessCpu.printCurrentState());
2236                //Slog.i(TAG, "Total CPU usage: "
2237                //        + mProcessCpu.getTotalCpuPercent() + "%");
2238
2239                // Slog the cpu usage if the property is set.
2240                if ("true".equals(SystemProperties.get("events.cpu"))) {
2241                    int user = mProcessCpuTracker.getLastUserTime();
2242                    int system = mProcessCpuTracker.getLastSystemTime();
2243                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2244                    int irq = mProcessCpuTracker.getLastIrqTime();
2245                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2246                    int idle = mProcessCpuTracker.getLastIdleTime();
2247
2248                    int total = user + system + iowait + irq + softIrq + idle;
2249                    if (total == 0) total = 1;
2250
2251                    EventLog.writeEvent(EventLogTags.CPU,
2252                            ((user+system+iowait+irq+softIrq) * 100) / total,
2253                            (user * 100) / total,
2254                            (system * 100) / total,
2255                            (iowait * 100) / total,
2256                            (irq * 100) / total,
2257                            (softIrq * 100) / total);
2258                }
2259            }
2260
2261            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2262            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2263            synchronized(bstats) {
2264                synchronized(mPidsSelfLocked) {
2265                    if (haveNewCpuStats) {
2266                        if (mOnBattery) {
2267                            int perc = bstats.startAddingCpuLocked();
2268                            int totalUTime = 0;
2269                            int totalSTime = 0;
2270                            final int N = mProcessCpuTracker.countStats();
2271                            for (int i=0; i<N; i++) {
2272                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2273                                if (!st.working) {
2274                                    continue;
2275                                }
2276                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2277                                int otherUTime = (st.rel_utime*perc)/100;
2278                                int otherSTime = (st.rel_stime*perc)/100;
2279                                totalUTime += otherUTime;
2280                                totalSTime += otherSTime;
2281                                if (pr != null) {
2282                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2283                                    if (ps == null || !ps.isActive()) {
2284                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2285                                                pr.info.uid, pr.processName);
2286                                    }
2287                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2288                                            st.rel_stime-otherSTime);
2289                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2290                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2291                                } else {
2292                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2293                                    if (ps == null || !ps.isActive()) {
2294                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2295                                                bstats.mapUid(st.uid), st.name);
2296                                    }
2297                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2298                                            st.rel_stime-otherSTime);
2299                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2300                                }
2301                            }
2302                            bstats.finishAddingCpuLocked(perc, totalUTime,
2303                                    totalSTime, cpuSpeedTimes);
2304                        }
2305                    }
2306                }
2307
2308                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2309                    mLastWriteTime = now;
2310                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2311                }
2312            }
2313        }
2314    }
2315
2316    @Override
2317    public void batteryNeedsCpuUpdate() {
2318        updateCpuStatsNow();
2319    }
2320
2321    @Override
2322    public void batteryPowerChanged(boolean onBattery) {
2323        // When plugging in, update the CPU stats first before changing
2324        // the plug state.
2325        updateCpuStatsNow();
2326        synchronized (this) {
2327            synchronized(mPidsSelfLocked) {
2328                mOnBattery = DEBUG_POWER ? true : onBattery;
2329            }
2330        }
2331    }
2332
2333    /**
2334     * Initialize the application bind args. These are passed to each
2335     * process when the bindApplication() IPC is sent to the process. They're
2336     * lazily setup to make sure the services are running when they're asked for.
2337     */
2338    private HashMap<String, IBinder> getCommonServicesLocked() {
2339        if (mAppBindArgs == null) {
2340            mAppBindArgs = new HashMap<String, IBinder>();
2341
2342            // Setup the application init args
2343            mAppBindArgs.put("package", ServiceManager.getService("package"));
2344            mAppBindArgs.put("window", ServiceManager.getService("window"));
2345            mAppBindArgs.put(Context.ALARM_SERVICE,
2346                    ServiceManager.getService(Context.ALARM_SERVICE));
2347        }
2348        return mAppBindArgs;
2349    }
2350
2351    final void setFocusedActivityLocked(ActivityRecord r) {
2352        if (mFocusedActivity != r) {
2353            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2354            mFocusedActivity = r;
2355            if (r.task != null && r.task.voiceInteractor != null) {
2356                startRunningVoiceLocked();
2357            } else {
2358                finishRunningVoiceLocked();
2359            }
2360            mStackSupervisor.setFocusedStack(r);
2361            if (r != null) {
2362                mWindowManager.setFocusedApp(r.appToken, true);
2363            }
2364            applyUpdateLockStateLocked(r);
2365        }
2366    }
2367
2368    final void clearFocusedActivity(ActivityRecord r) {
2369        if (mFocusedActivity == r) {
2370            mFocusedActivity = null;
2371        }
2372    }
2373
2374    @Override
2375    public void setFocusedStack(int stackId) {
2376        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2377        synchronized (ActivityManagerService.this) {
2378            ActivityStack stack = mStackSupervisor.getStack(stackId);
2379            if (stack != null) {
2380                ActivityRecord r = stack.topRunningActivityLocked(null);
2381                if (r != null) {
2382                    setFocusedActivityLocked(r);
2383                }
2384            }
2385        }
2386    }
2387
2388    @Override
2389    public void notifyActivityDrawn(IBinder token) {
2390        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2391        synchronized (this) {
2392            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2393            if (r != null) {
2394                r.task.stack.notifyActivityDrawnLocked(r);
2395            }
2396        }
2397    }
2398
2399    final void applyUpdateLockStateLocked(ActivityRecord r) {
2400        // Modifications to the UpdateLock state are done on our handler, outside
2401        // the activity manager's locks.  The new state is determined based on the
2402        // state *now* of the relevant activity record.  The object is passed to
2403        // the handler solely for logging detail, not to be consulted/modified.
2404        final boolean nextState = r != null && r.immersive;
2405        mHandler.sendMessage(
2406                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2407    }
2408
2409    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2410        Message msg = Message.obtain();
2411        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2412        msg.obj = r.task.askedCompatMode ? null : r;
2413        mHandler.sendMessage(msg);
2414    }
2415
2416    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2417            String what, Object obj, ProcessRecord srcApp) {
2418        app.lastActivityTime = now;
2419
2420        if (app.activities.size() > 0) {
2421            // Don't want to touch dependent processes that are hosting activities.
2422            return index;
2423        }
2424
2425        int lrui = mLruProcesses.lastIndexOf(app);
2426        if (lrui < 0) {
2427            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2428                    + what + " " + obj + " from " + srcApp);
2429            return index;
2430        }
2431
2432        if (lrui >= index) {
2433            // Don't want to cause this to move dependent processes *back* in the
2434            // list as if they were less frequently used.
2435            return index;
2436        }
2437
2438        if (lrui >= mLruProcessActivityStart) {
2439            // Don't want to touch dependent processes that are hosting activities.
2440            return index;
2441        }
2442
2443        mLruProcesses.remove(lrui);
2444        if (index > 0) {
2445            index--;
2446        }
2447        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2448                + " in LRU list: " + app);
2449        mLruProcesses.add(index, app);
2450        return index;
2451    }
2452
2453    final void removeLruProcessLocked(ProcessRecord app) {
2454        int lrui = mLruProcesses.lastIndexOf(app);
2455        if (lrui >= 0) {
2456            if (lrui <= mLruProcessActivityStart) {
2457                mLruProcessActivityStart--;
2458            }
2459            if (lrui <= mLruProcessServiceStart) {
2460                mLruProcessServiceStart--;
2461            }
2462            mLruProcesses.remove(lrui);
2463        }
2464    }
2465
2466    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2467            ProcessRecord client) {
2468        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2469                || app.treatLikeActivity;
2470        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2471        if (!activityChange && hasActivity) {
2472            // The process has activities, so we are only allowing activity-based adjustments
2473            // to move it.  It should be kept in the front of the list with other
2474            // processes that have activities, and we don't want those to change their
2475            // order except due to activity operations.
2476            return;
2477        }
2478
2479        mLruSeq++;
2480        final long now = SystemClock.uptimeMillis();
2481        app.lastActivityTime = now;
2482
2483        // First a quick reject: if the app is already at the position we will
2484        // put it, then there is nothing to do.
2485        if (hasActivity) {
2486            final int N = mLruProcesses.size();
2487            if (N > 0 && mLruProcesses.get(N-1) == app) {
2488                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2489                return;
2490            }
2491        } else {
2492            if (mLruProcessServiceStart > 0
2493                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2494                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2495                return;
2496            }
2497        }
2498
2499        int lrui = mLruProcesses.lastIndexOf(app);
2500
2501        if (app.persistent && lrui >= 0) {
2502            // We don't care about the position of persistent processes, as long as
2503            // they are in the list.
2504            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2505            return;
2506        }
2507
2508        /* In progress: compute new position first, so we can avoid doing work
2509           if the process is not actually going to move.  Not yet working.
2510        int addIndex;
2511        int nextIndex;
2512        boolean inActivity = false, inService = false;
2513        if (hasActivity) {
2514            // Process has activities, put it at the very tipsy-top.
2515            addIndex = mLruProcesses.size();
2516            nextIndex = mLruProcessServiceStart;
2517            inActivity = true;
2518        } else if (hasService) {
2519            // Process has services, put it at the top of the service list.
2520            addIndex = mLruProcessActivityStart;
2521            nextIndex = mLruProcessServiceStart;
2522            inActivity = true;
2523            inService = true;
2524        } else  {
2525            // Process not otherwise of interest, it goes to the top of the non-service area.
2526            addIndex = mLruProcessServiceStart;
2527            if (client != null) {
2528                int clientIndex = mLruProcesses.lastIndexOf(client);
2529                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2530                        + app);
2531                if (clientIndex >= 0 && addIndex > clientIndex) {
2532                    addIndex = clientIndex;
2533                }
2534            }
2535            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2536        }
2537
2538        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2539                + mLruProcessActivityStart + "): " + app);
2540        */
2541
2542        if (lrui >= 0) {
2543            if (lrui < mLruProcessActivityStart) {
2544                mLruProcessActivityStart--;
2545            }
2546            if (lrui < mLruProcessServiceStart) {
2547                mLruProcessServiceStart--;
2548            }
2549            /*
2550            if (addIndex > lrui) {
2551                addIndex--;
2552            }
2553            if (nextIndex > lrui) {
2554                nextIndex--;
2555            }
2556            */
2557            mLruProcesses.remove(lrui);
2558        }
2559
2560        /*
2561        mLruProcesses.add(addIndex, app);
2562        if (inActivity) {
2563            mLruProcessActivityStart++;
2564        }
2565        if (inService) {
2566            mLruProcessActivityStart++;
2567        }
2568        */
2569
2570        int nextIndex;
2571        if (hasActivity) {
2572            final int N = mLruProcesses.size();
2573            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2574                // Process doesn't have activities, but has clients with
2575                // activities...  move it up, but one below the top (the top
2576                // should always have a real activity).
2577                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2578                mLruProcesses.add(N-1, app);
2579                // To keep it from spamming the LRU list (by making a bunch of clients),
2580                // we will push down any other entries owned by the app.
2581                final int uid = app.info.uid;
2582                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2583                    ProcessRecord subProc = mLruProcesses.get(i);
2584                    if (subProc.info.uid == uid) {
2585                        // We want to push this one down the list.  If the process after
2586                        // it is for the same uid, however, don't do so, because we don't
2587                        // want them internally to be re-ordered.
2588                        if (mLruProcesses.get(i-1).info.uid != uid) {
2589                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2590                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2591                            ProcessRecord tmp = mLruProcesses.get(i);
2592                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2593                            mLruProcesses.set(i-1, tmp);
2594                            i--;
2595                        }
2596                    } else {
2597                        // A gap, we can stop here.
2598                        break;
2599                    }
2600                }
2601            } else {
2602                // Process has activities, put it at the very tipsy-top.
2603                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2604                mLruProcesses.add(app);
2605            }
2606            nextIndex = mLruProcessServiceStart;
2607        } else if (hasService) {
2608            // Process has services, put it at the top of the service list.
2609            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2610            mLruProcesses.add(mLruProcessActivityStart, app);
2611            nextIndex = mLruProcessServiceStart;
2612            mLruProcessActivityStart++;
2613        } else  {
2614            // Process not otherwise of interest, it goes to the top of the non-service area.
2615            int index = mLruProcessServiceStart;
2616            if (client != null) {
2617                // If there is a client, don't allow the process to be moved up higher
2618                // in the list than that client.
2619                int clientIndex = mLruProcesses.lastIndexOf(client);
2620                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2621                        + " when updating " + app);
2622                if (clientIndex <= lrui) {
2623                    // Don't allow the client index restriction to push it down farther in the
2624                    // list than it already is.
2625                    clientIndex = lrui;
2626                }
2627                if (clientIndex >= 0 && index > clientIndex) {
2628                    index = clientIndex;
2629                }
2630            }
2631            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2632            mLruProcesses.add(index, app);
2633            nextIndex = index-1;
2634            mLruProcessActivityStart++;
2635            mLruProcessServiceStart++;
2636        }
2637
2638        // If the app is currently using a content provider or service,
2639        // bump those processes as well.
2640        for (int j=app.connections.size()-1; j>=0; j--) {
2641            ConnectionRecord cr = app.connections.valueAt(j);
2642            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2643                    && cr.binding.service.app != null
2644                    && cr.binding.service.app.lruSeq != mLruSeq
2645                    && !cr.binding.service.app.persistent) {
2646                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2647                        "service connection", cr, app);
2648            }
2649        }
2650        for (int j=app.conProviders.size()-1; j>=0; j--) {
2651            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2652            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2653                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2654                        "provider reference", cpr, app);
2655            }
2656        }
2657    }
2658
2659    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2660        if (uid == Process.SYSTEM_UID) {
2661            // The system gets to run in any process.  If there are multiple
2662            // processes with the same uid, just pick the first (this
2663            // should never happen).
2664            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2665            if (procs == null) return null;
2666            final int N = procs.size();
2667            for (int i = 0; i < N; i++) {
2668                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2669            }
2670        }
2671        ProcessRecord proc = mProcessNames.get(processName, uid);
2672        if (false && proc != null && !keepIfLarge
2673                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2674                && proc.lastCachedPss >= 4000) {
2675            // Turn this condition on to cause killing to happen regularly, for testing.
2676            if (proc.baseProcessTracker != null) {
2677                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2678            }
2679            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2680                    + "k from cached");
2681        } else if (proc != null && !keepIfLarge
2682                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2683                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2684            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2685            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2686                if (proc.baseProcessTracker != null) {
2687                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2688                }
2689                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2690                        + "k from cached");
2691            }
2692        }
2693        return proc;
2694    }
2695
2696    void ensurePackageDexOpt(String packageName) {
2697        IPackageManager pm = AppGlobals.getPackageManager();
2698        try {
2699            if (pm.performDexOpt(packageName)) {
2700                mDidDexOpt = true;
2701            }
2702        } catch (RemoteException e) {
2703        }
2704    }
2705
2706    boolean isNextTransitionForward() {
2707        int transit = mWindowManager.getPendingAppTransition();
2708        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2709                || transit == AppTransition.TRANSIT_TASK_OPEN
2710                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2711    }
2712
2713    final ProcessRecord startProcessLocked(String processName,
2714            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2715            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2716            boolean isolated, boolean keepIfLarge) {
2717        ProcessRecord app;
2718        if (!isolated) {
2719            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2720        } else {
2721            // If this is an isolated process, it can't re-use an existing process.
2722            app = null;
2723        }
2724        // We don't have to do anything more if:
2725        // (1) There is an existing application record; and
2726        // (2) The caller doesn't think it is dead, OR there is no thread
2727        //     object attached to it so we know it couldn't have crashed; and
2728        // (3) There is a pid assigned to it, so it is either starting or
2729        //     already running.
2730        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2731                + " app=" + app + " knownToBeDead=" + knownToBeDead
2732                + " thread=" + (app != null ? app.thread : null)
2733                + " pid=" + (app != null ? app.pid : -1));
2734        if (app != null && app.pid > 0) {
2735            if (!knownToBeDead || app.thread == null) {
2736                // We already have the app running, or are waiting for it to
2737                // come up (we have a pid but not yet its thread), so keep it.
2738                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2739                // If this is a new package in the process, add the package to the list
2740                app.addPackage(info.packageName, mProcessStats);
2741                return app;
2742            }
2743
2744            // An application record is attached to a previous process,
2745            // clean it up now.
2746            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2747            handleAppDiedLocked(app, true, true);
2748        }
2749
2750        String hostingNameStr = hostingName != null
2751                ? hostingName.flattenToShortString() : null;
2752
2753        if (!isolated) {
2754            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2755                // If we are in the background, then check to see if this process
2756                // is bad.  If so, we will just silently fail.
2757                if (mBadProcesses.get(info.processName, info.uid) != null) {
2758                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2759                            + "/" + info.processName);
2760                    return null;
2761                }
2762            } else {
2763                // When the user is explicitly starting a process, then clear its
2764                // crash count so that we won't make it bad until they see at
2765                // least one crash dialog again, and make the process good again
2766                // if it had been bad.
2767                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2768                        + "/" + info.processName);
2769                mProcessCrashTimes.remove(info.processName, info.uid);
2770                if (mBadProcesses.get(info.processName, info.uid) != null) {
2771                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2772                            UserHandle.getUserId(info.uid), info.uid,
2773                            info.processName);
2774                    mBadProcesses.remove(info.processName, info.uid);
2775                    if (app != null) {
2776                        app.bad = false;
2777                    }
2778                }
2779            }
2780        }
2781
2782        if (app == null) {
2783            app = newProcessRecordLocked(info, processName, isolated);
2784            if (app == null) {
2785                Slog.w(TAG, "Failed making new process record for "
2786                        + processName + "/" + info.uid + " isolated=" + isolated);
2787                return null;
2788            }
2789            mProcessNames.put(processName, app.uid, app);
2790            if (isolated) {
2791                mIsolatedProcesses.put(app.uid, app);
2792            }
2793        } else {
2794            // If this is a new package in the process, add the package to the list
2795            app.addPackage(info.packageName, mProcessStats);
2796        }
2797
2798        // If the system is not ready yet, then hold off on starting this
2799        // process until it is.
2800        if (!mProcessesReady
2801                && !isAllowedWhileBooting(info)
2802                && !allowWhileBooting) {
2803            if (!mProcessesOnHold.contains(app)) {
2804                mProcessesOnHold.add(app);
2805            }
2806            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2807            return app;
2808        }
2809
2810        startProcessLocked(app, hostingType, hostingNameStr);
2811        return (app.pid != 0) ? app : null;
2812    }
2813
2814    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2815        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2816    }
2817
2818    private final void startProcessLocked(ProcessRecord app,
2819            String hostingType, String hostingNameStr) {
2820        if (app.pid > 0 && app.pid != MY_PID) {
2821            synchronized (mPidsSelfLocked) {
2822                mPidsSelfLocked.remove(app.pid);
2823                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2824            }
2825            app.setPid(0);
2826        }
2827
2828        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2829                "startProcessLocked removing on hold: " + app);
2830        mProcessesOnHold.remove(app);
2831
2832        updateCpuStats();
2833
2834        try {
2835            int uid = app.uid;
2836
2837            int[] gids = null;
2838            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2839            if (!app.isolated) {
2840                int[] permGids = null;
2841                try {
2842                    final PackageManager pm = mContext.getPackageManager();
2843                    permGids = pm.getPackageGids(app.info.packageName);
2844
2845                    if (Environment.isExternalStorageEmulated()) {
2846                        if (pm.checkPermission(
2847                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2848                                app.info.packageName) == PERMISSION_GRANTED) {
2849                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2850                        } else {
2851                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2852                        }
2853                    }
2854                } catch (PackageManager.NameNotFoundException e) {
2855                    Slog.w(TAG, "Unable to retrieve gids", e);
2856                }
2857
2858                /*
2859                 * Add shared application GID so applications can share some
2860                 * resources like shared libraries
2861                 */
2862                if (permGids == null) {
2863                    gids = new int[1];
2864                } else {
2865                    gids = new int[permGids.length + 1];
2866                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2867                }
2868                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2869            }
2870            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2871                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2872                        && mTopComponent != null
2873                        && app.processName.equals(mTopComponent.getPackageName())) {
2874                    uid = 0;
2875                }
2876                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2877                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2878                    uid = 0;
2879                }
2880            }
2881            int debugFlags = 0;
2882            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2883                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2884                // Also turn on CheckJNI for debuggable apps. It's quite
2885                // awkward to turn on otherwise.
2886                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2887            }
2888            // Run the app in safe mode if its manifest requests so or the
2889            // system is booted in safe mode.
2890            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2891                mSafeMode == true) {
2892                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2893            }
2894            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2895                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2896            }
2897            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.assert"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2902            }
2903
2904            String requiredAbi = app.info.requiredCpuAbi;
2905            if (requiredAbi == null) {
2906                requiredAbi = Build.SUPPORTED_ABIS[0];
2907            }
2908
2909            // Start the process.  It will either succeed and return a result containing
2910            // the PID of the new process, or else throw a RuntimeException.
2911            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2912                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2913                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2914
2915            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2916            synchronized (bs) {
2917                if (bs.isOnBattery()) {
2918                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2919                }
2920            }
2921
2922            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2923                    UserHandle.getUserId(uid), startResult.pid, uid,
2924                    app.processName, hostingType,
2925                    hostingNameStr != null ? hostingNameStr : "");
2926
2927            if (app.persistent) {
2928                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2929            }
2930
2931            StringBuilder buf = mStringBuilder;
2932            buf.setLength(0);
2933            buf.append("Start proc ");
2934            buf.append(app.processName);
2935            buf.append(" for ");
2936            buf.append(hostingType);
2937            if (hostingNameStr != null) {
2938                buf.append(" ");
2939                buf.append(hostingNameStr);
2940            }
2941            buf.append(": pid=");
2942            buf.append(startResult.pid);
2943            buf.append(" uid=");
2944            buf.append(uid);
2945            buf.append(" gids={");
2946            if (gids != null) {
2947                for (int gi=0; gi<gids.length; gi++) {
2948                    if (gi != 0) buf.append(", ");
2949                    buf.append(gids[gi]);
2950
2951                }
2952            }
2953            buf.append("}");
2954            Slog.i(TAG, buf.toString());
2955            app.setPid(startResult.pid);
2956            app.usingWrapper = startResult.usingWrapper;
2957            app.removed = false;
2958            synchronized (mPidsSelfLocked) {
2959                this.mPidsSelfLocked.put(startResult.pid, app);
2960                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2961                msg.obj = app;
2962                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2963                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2964            }
2965            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2966                    app.processName, app.info.uid);
2967            if (app.isolated) {
2968                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2969            }
2970        } catch (RuntimeException e) {
2971            // XXX do better error recovery.
2972            app.setPid(0);
2973            Slog.e(TAG, "Failure starting process " + app.processName, e);
2974        }
2975    }
2976
2977    void updateUsageStats(ActivityRecord component, boolean resumed) {
2978        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2979        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2980        if (resumed) {
2981            mUsageStatsService.noteResumeComponent(component.realActivity);
2982            synchronized (stats) {
2983                stats.noteActivityResumedLocked(component.app.uid);
2984            }
2985        } else {
2986            mUsageStatsService.notePauseComponent(component.realActivity);
2987            synchronized (stats) {
2988                stats.noteActivityPausedLocked(component.app.uid);
2989            }
2990        }
2991    }
2992
2993    Intent getHomeIntent() {
2994        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2995        intent.setComponent(mTopComponent);
2996        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2997            intent.addCategory(Intent.CATEGORY_HOME);
2998        }
2999        return intent;
3000    }
3001
3002    boolean startHomeActivityLocked(int userId) {
3003        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3004                && mTopAction == null) {
3005            // We are running in factory test mode, but unable to find
3006            // the factory test app, so just sit around displaying the
3007            // error message and don't try to start anything.
3008            return false;
3009        }
3010        Intent intent = getHomeIntent();
3011        ActivityInfo aInfo =
3012            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3013        if (aInfo != null) {
3014            intent.setComponent(new ComponentName(
3015                    aInfo.applicationInfo.packageName, aInfo.name));
3016            // Don't do this if the home app is currently being
3017            // instrumented.
3018            aInfo = new ActivityInfo(aInfo);
3019            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3020            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3021                    aInfo.applicationInfo.uid, true);
3022            if (app == null || app.instrumentationClass == null) {
3023                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3024                mStackSupervisor.startHomeActivity(intent, aInfo);
3025            }
3026        }
3027
3028        return true;
3029    }
3030
3031    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3032        ActivityInfo ai = null;
3033        ComponentName comp = intent.getComponent();
3034        try {
3035            if (comp != null) {
3036                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3037            } else {
3038                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3039                        intent,
3040                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3041                            flags, userId);
3042
3043                if (info != null) {
3044                    ai = info.activityInfo;
3045                }
3046            }
3047        } catch (RemoteException e) {
3048            // ignore
3049        }
3050
3051        return ai;
3052    }
3053
3054    /**
3055     * Starts the "new version setup screen" if appropriate.
3056     */
3057    void startSetupActivityLocked() {
3058        // Only do this once per boot.
3059        if (mCheckedForSetup) {
3060            return;
3061        }
3062
3063        // We will show this screen if the current one is a different
3064        // version than the last one shown, and we are not running in
3065        // low-level factory test mode.
3066        final ContentResolver resolver = mContext.getContentResolver();
3067        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3068                Settings.Global.getInt(resolver,
3069                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3070            mCheckedForSetup = true;
3071
3072            // See if we should be showing the platform update setup UI.
3073            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3074            List<ResolveInfo> ris = mContext.getPackageManager()
3075                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3076
3077            // We don't allow third party apps to replace this.
3078            ResolveInfo ri = null;
3079            for (int i=0; ris != null && i<ris.size(); i++) {
3080                if ((ris.get(i).activityInfo.applicationInfo.flags
3081                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3082                    ri = ris.get(i);
3083                    break;
3084                }
3085            }
3086
3087            if (ri != null) {
3088                String vers = ri.activityInfo.metaData != null
3089                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3090                        : null;
3091                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3092                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3093                            Intent.METADATA_SETUP_VERSION);
3094                }
3095                String lastVers = Settings.Secure.getString(
3096                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3097                if (vers != null && !vers.equals(lastVers)) {
3098                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3099                    intent.setComponent(new ComponentName(
3100                            ri.activityInfo.packageName, ri.activityInfo.name));
3101                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3102                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3103                }
3104            }
3105        }
3106    }
3107
3108    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3109        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3110    }
3111
3112    void enforceNotIsolatedCaller(String caller) {
3113        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3114            throw new SecurityException("Isolated process not allowed to call " + caller);
3115        }
3116    }
3117
3118    @Override
3119    public int getFrontActivityScreenCompatMode() {
3120        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3121        synchronized (this) {
3122            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3123        }
3124    }
3125
3126    @Override
3127    public void setFrontActivityScreenCompatMode(int mode) {
3128        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3129                "setFrontActivityScreenCompatMode");
3130        synchronized (this) {
3131            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3132        }
3133    }
3134
3135    @Override
3136    public int getPackageScreenCompatMode(String packageName) {
3137        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3138        synchronized (this) {
3139            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3140        }
3141    }
3142
3143    @Override
3144    public void setPackageScreenCompatMode(String packageName, int mode) {
3145        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3146                "setPackageScreenCompatMode");
3147        synchronized (this) {
3148            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3149        }
3150    }
3151
3152    @Override
3153    public boolean getPackageAskScreenCompat(String packageName) {
3154        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3155        synchronized (this) {
3156            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3157        }
3158    }
3159
3160    @Override
3161    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3162        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3163                "setPackageAskScreenCompat");
3164        synchronized (this) {
3165            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3166        }
3167    }
3168
3169    private void dispatchProcessesChanged() {
3170        int N;
3171        synchronized (this) {
3172            N = mPendingProcessChanges.size();
3173            if (mActiveProcessChanges.length < N) {
3174                mActiveProcessChanges = new ProcessChangeItem[N];
3175            }
3176            mPendingProcessChanges.toArray(mActiveProcessChanges);
3177            mAvailProcessChanges.addAll(mPendingProcessChanges);
3178            mPendingProcessChanges.clear();
3179            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3180        }
3181
3182        int i = mProcessObservers.beginBroadcast();
3183        while (i > 0) {
3184            i--;
3185            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3186            if (observer != null) {
3187                try {
3188                    for (int j=0; j<N; j++) {
3189                        ProcessChangeItem item = mActiveProcessChanges[j];
3190                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3191                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3192                                    + item.pid + " uid=" + item.uid + ": "
3193                                    + item.foregroundActivities);
3194                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3195                                    item.foregroundActivities);
3196                        }
3197                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3198                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3199                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3200                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3201                        }
3202                    }
3203                } catch (RemoteException e) {
3204                }
3205            }
3206        }
3207        mProcessObservers.finishBroadcast();
3208    }
3209
3210    private void dispatchProcessDied(int pid, int uid) {
3211        int i = mProcessObservers.beginBroadcast();
3212        while (i > 0) {
3213            i--;
3214            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3215            if (observer != null) {
3216                try {
3217                    observer.onProcessDied(pid, uid);
3218                } catch (RemoteException e) {
3219                }
3220            }
3221        }
3222        mProcessObservers.finishBroadcast();
3223    }
3224
3225    final void doPendingActivityLaunchesLocked(boolean doResume) {
3226        final int N = mPendingActivityLaunches.size();
3227        if (N <= 0) {
3228            return;
3229        }
3230        for (int i=0; i<N; i++) {
3231            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3232            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3233                    doResume && i == (N-1), null);
3234        }
3235        mPendingActivityLaunches.clear();
3236    }
3237
3238    @Override
3239    public final int startActivity(IApplicationThread caller, String callingPackage,
3240            Intent intent, String resolvedType, IBinder resultTo,
3241            String resultWho, int requestCode, int startFlags,
3242            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3243        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3244                resultWho, requestCode,
3245                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3246    }
3247
3248    @Override
3249    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3250            Intent intent, String resolvedType, IBinder resultTo,
3251            String resultWho, int requestCode, int startFlags,
3252            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3253        enforceNotIsolatedCaller("startActivity");
3254        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3255                false, true, "startActivity", null);
3256        // TODO: Switch to user app stacks here.
3257        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3258                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3259                null, null, options, userId, null);
3260    }
3261
3262    @Override
3263    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3264            Intent intent, String resolvedType, IBinder resultTo,
3265            String resultWho, int requestCode, int startFlags, String profileFile,
3266            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3267        enforceNotIsolatedCaller("startActivityAndWait");
3268        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3269                false, true, "startActivityAndWait", null);
3270        WaitResult res = new WaitResult();
3271        // TODO: Switch to user app stacks here.
3272        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3273                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3274                res, null, options, UserHandle.getCallingUserId(), null);
3275        return res;
3276    }
3277
3278    @Override
3279    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3280            Intent intent, String resolvedType, IBinder resultTo,
3281            String resultWho, int requestCode, int startFlags, Configuration config,
3282            Bundle options, int userId) {
3283        enforceNotIsolatedCaller("startActivityWithConfig");
3284        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3285                false, true, "startActivityWithConfig", null);
3286        // TODO: Switch to user app stacks here.
3287        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3288                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3289                null, null, null, config, options, userId, null);
3290        return ret;
3291    }
3292
3293    @Override
3294    public int startActivityIntentSender(IApplicationThread caller,
3295            IntentSender intent, Intent fillInIntent, String resolvedType,
3296            IBinder resultTo, String resultWho, int requestCode,
3297            int flagsMask, int flagsValues, Bundle options) {
3298        enforceNotIsolatedCaller("startActivityIntentSender");
3299        // Refuse possible leaked file descriptors
3300        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3301            throw new IllegalArgumentException("File descriptors passed in Intent");
3302        }
3303
3304        IIntentSender sender = intent.getTarget();
3305        if (!(sender instanceof PendingIntentRecord)) {
3306            throw new IllegalArgumentException("Bad PendingIntent object");
3307        }
3308
3309        PendingIntentRecord pir = (PendingIntentRecord)sender;
3310
3311        synchronized (this) {
3312            // If this is coming from the currently resumed activity, it is
3313            // effectively saying that app switches are allowed at this point.
3314            final ActivityStack stack = getFocusedStack();
3315            if (stack.mResumedActivity != null &&
3316                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3317                mAppSwitchesAllowedTime = 0;
3318            }
3319        }
3320        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3321                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3322        return ret;
3323    }
3324
3325    @Override
3326    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3327            Intent intent, String resolvedType, IVoiceInteractionSession session,
3328            IVoiceInteractor interactor, int startFlags, String profileFile,
3329            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3330        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3331                != PackageManager.PERMISSION_GRANTED) {
3332            String msg = "Permission Denial: startVoiceActivity() from pid="
3333                    + Binder.getCallingPid()
3334                    + ", uid=" + Binder.getCallingUid()
3335                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3336            Slog.w(TAG, msg);
3337            throw new SecurityException(msg);
3338        }
3339        if (session == null || interactor == null) {
3340            throw new NullPointerException("null session or interactor");
3341        }
3342        userId = handleIncomingUser(callingPid, callingUid, userId,
3343                false, true, "startVoiceActivity", null);
3344        // TODO: Switch to user app stacks here.
3345        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3346                resolvedType, session, interactor, null, null, 0, startFlags,
3347                profileFile, profileFd, null, null, options, userId, null);
3348    }
3349
3350    @Override
3351    public boolean startNextMatchingActivity(IBinder callingActivity,
3352            Intent intent, Bundle options) {
3353        // Refuse possible leaked file descriptors
3354        if (intent != null && intent.hasFileDescriptors() == true) {
3355            throw new IllegalArgumentException("File descriptors passed in Intent");
3356        }
3357
3358        synchronized (this) {
3359            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3360            if (r == null) {
3361                ActivityOptions.abort(options);
3362                return false;
3363            }
3364            if (r.app == null || r.app.thread == null) {
3365                // The caller is not running...  d'oh!
3366                ActivityOptions.abort(options);
3367                return false;
3368            }
3369            intent = new Intent(intent);
3370            // The caller is not allowed to change the data.
3371            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3372            // And we are resetting to find the next component...
3373            intent.setComponent(null);
3374
3375            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3376
3377            ActivityInfo aInfo = null;
3378            try {
3379                List<ResolveInfo> resolves =
3380                    AppGlobals.getPackageManager().queryIntentActivities(
3381                            intent, r.resolvedType,
3382                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3383                            UserHandle.getCallingUserId());
3384
3385                // Look for the original activity in the list...
3386                final int N = resolves != null ? resolves.size() : 0;
3387                for (int i=0; i<N; i++) {
3388                    ResolveInfo rInfo = resolves.get(i);
3389                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3390                            && rInfo.activityInfo.name.equals(r.info.name)) {
3391                        // We found the current one...  the next matching is
3392                        // after it.
3393                        i++;
3394                        if (i<N) {
3395                            aInfo = resolves.get(i).activityInfo;
3396                        }
3397                        if (debug) {
3398                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3399                                    + "/" + r.info.name);
3400                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3401                                    + "/" + aInfo.name);
3402                        }
3403                        break;
3404                    }
3405                }
3406            } catch (RemoteException e) {
3407            }
3408
3409            if (aInfo == null) {
3410                // Nobody who is next!
3411                ActivityOptions.abort(options);
3412                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3413                return false;
3414            }
3415
3416            intent.setComponent(new ComponentName(
3417                    aInfo.applicationInfo.packageName, aInfo.name));
3418            intent.setFlags(intent.getFlags()&~(
3419                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3420                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3421                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3422                    Intent.FLAG_ACTIVITY_NEW_TASK));
3423
3424            // Okay now we need to start the new activity, replacing the
3425            // currently running activity.  This is a little tricky because
3426            // we want to start the new one as if the current one is finished,
3427            // but not finish the current one first so that there is no flicker.
3428            // And thus...
3429            final boolean wasFinishing = r.finishing;
3430            r.finishing = true;
3431
3432            // Propagate reply information over to the new activity.
3433            final ActivityRecord resultTo = r.resultTo;
3434            final String resultWho = r.resultWho;
3435            final int requestCode = r.requestCode;
3436            r.resultTo = null;
3437            if (resultTo != null) {
3438                resultTo.removeResultsLocked(r, resultWho, requestCode);
3439            }
3440
3441            final long origId = Binder.clearCallingIdentity();
3442            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3443                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3444                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3445                    options, false, null, null);
3446            Binder.restoreCallingIdentity(origId);
3447
3448            r.finishing = wasFinishing;
3449            if (res != ActivityManager.START_SUCCESS) {
3450                return false;
3451            }
3452            return true;
3453        }
3454    }
3455
3456    final int startActivityInPackage(int uid, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo,
3458            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3459                    IActivityContainer container) {
3460
3461        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3462                false, true, "startActivityInPackage", null);
3463
3464        // TODO: Switch to user app stacks here.
3465        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3466                null, null, resultTo, resultWho, requestCode, startFlags,
3467                null, null, null, null, options, userId, container);
3468        return ret;
3469    }
3470
3471    @Override
3472    public final int startActivities(IApplicationThread caller, String callingPackage,
3473            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3474            int userId) {
3475        enforceNotIsolatedCaller("startActivities");
3476        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3477                false, true, "startActivity", null);
3478        // TODO: Switch to user app stacks here.
3479        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3480                resolvedTypes, resultTo, options, userId);
3481        return ret;
3482    }
3483
3484    final int startActivitiesInPackage(int uid, String callingPackage,
3485            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3486            Bundle options, int userId) {
3487
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3489                false, true, "startActivityInPackage", null);
3490        // TODO: Switch to user app stacks here.
3491        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3492                resultTo, options, userId);
3493        return ret;
3494    }
3495
3496    final void addRecentTaskLocked(TaskRecord task) {
3497        int N = mRecentTasks.size();
3498        // Quick case: check if the top-most recent task is the same.
3499        if (N > 0 && mRecentTasks.get(0) == task) {
3500            return;
3501        }
3502        // Another quick case: never add voice sessions.
3503        if (task.voiceSession != null) {
3504            return;
3505        }
3506        // Remove any existing entries that are the same kind of task.
3507        final Intent intent = task.intent;
3508        final boolean document = intent != null && intent.isDocument();
3509        for (int i=0; i<N; i++) {
3510            TaskRecord tr = mRecentTasks.get(i);
3511            if (task != tr) {
3512                if (task.userId != tr.userId) {
3513                    continue;
3514                }
3515                final Intent trIntent = tr.intent;
3516                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3517                    (intent == null || !intent.filterEquals(trIntent))) {
3518                    continue;
3519                }
3520                if (document || trIntent != null && trIntent.isDocument()) {
3521                    // Document tasks do not match other tasks.
3522                    continue;
3523                }
3524            }
3525
3526            // Either task and tr are the same or, their affinities match or their intents match
3527            // and neither of them is a document.
3528            tr.disposeThumbnail();
3529            mRecentTasks.remove(i);
3530            i--;
3531            N--;
3532            if (task.intent == null) {
3533                // If the new recent task we are adding is not fully
3534                // specified, then replace it with the existing recent task.
3535                task = tr;
3536            }
3537        }
3538        if (N >= MAX_RECENT_TASKS) {
3539            mRecentTasks.remove(N-1).disposeThumbnail();
3540        }
3541        mRecentTasks.add(0, task);
3542    }
3543
3544    @Override
3545    public void reportActivityFullyDrawn(IBinder token) {
3546        synchronized (this) {
3547            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3548            if (r == null) {
3549                return;
3550            }
3551            r.reportFullyDrawnLocked();
3552        }
3553    }
3554
3555    @Override
3556    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3557        synchronized (this) {
3558            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3559            if (r == null) {
3560                return;
3561            }
3562            final long origId = Binder.clearCallingIdentity();
3563            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3564            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3565                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3566            if (config != null) {
3567                r.frozenBeforeDestroy = true;
3568                if (!updateConfigurationLocked(config, r, false, false)) {
3569                    mStackSupervisor.resumeTopActivitiesLocked();
3570                }
3571            }
3572            Binder.restoreCallingIdentity(origId);
3573        }
3574    }
3575
3576    @Override
3577    public int getRequestedOrientation(IBinder token) {
3578        synchronized (this) {
3579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3580            if (r == null) {
3581                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3582            }
3583            return mWindowManager.getAppOrientation(r.appToken);
3584        }
3585    }
3586
3587    /**
3588     * This is the internal entry point for handling Activity.finish().
3589     *
3590     * @param token The Binder token referencing the Activity we want to finish.
3591     * @param resultCode Result code, if any, from this Activity.
3592     * @param resultData Result data (Intent), if any, from this Activity.
3593     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3594     *            the root Activity in the task.
3595     *
3596     * @return Returns true if the activity successfully finished, or false if it is still running.
3597     */
3598    @Override
3599    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3600            boolean finishTask) {
3601        // Refuse possible leaked file descriptors
3602        if (resultData != null && resultData.hasFileDescriptors() == true) {
3603            throw new IllegalArgumentException("File descriptors passed in Intent");
3604        }
3605
3606        synchronized(this) {
3607            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3608            if (r == null) {
3609                return true;
3610            }
3611            // Keep track of the root activity of the task before we finish it
3612            TaskRecord tr = r.task;
3613            ActivityRecord rootR = tr.getRootActivity();
3614            if (mController != null) {
3615                // Find the first activity that is not finishing.
3616                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3617                if (next != null) {
3618                    // ask watcher if this is allowed
3619                    boolean resumeOK = true;
3620                    try {
3621                        resumeOK = mController.activityResuming(next.packageName);
3622                    } catch (RemoteException e) {
3623                        mController = null;
3624                        Watchdog.getInstance().setActivityController(null);
3625                    }
3626
3627                    if (!resumeOK) {
3628                        return false;
3629                    }
3630                }
3631            }
3632            final long origId = Binder.clearCallingIdentity();
3633            try {
3634                boolean res;
3635                if (finishTask && r == rootR) {
3636                    // If requested, remove the task that is associated to this activity only if it
3637                    // was the root activity in the task.  The result code and data is ignored because
3638                    // we don't support returning them across task boundaries.
3639                    res = removeTaskByIdLocked(tr.taskId, 0);
3640                } else {
3641                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3642                            resultData, "app-request", true);
3643                }
3644                return res;
3645            } finally {
3646                Binder.restoreCallingIdentity(origId);
3647            }
3648        }
3649    }
3650
3651    @Override
3652    public final void finishHeavyWeightApp() {
3653        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3654                != PackageManager.PERMISSION_GRANTED) {
3655            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3656                    + Binder.getCallingPid()
3657                    + ", uid=" + Binder.getCallingUid()
3658                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3659            Slog.w(TAG, msg);
3660            throw new SecurityException(msg);
3661        }
3662
3663        synchronized(this) {
3664            if (mHeavyWeightProcess == null) {
3665                return;
3666            }
3667
3668            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3669                    mHeavyWeightProcess.activities);
3670            for (int i=0; i<activities.size(); i++) {
3671                ActivityRecord r = activities.get(i);
3672                if (!r.finishing) {
3673                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3674                            null, "finish-heavy", true);
3675                }
3676            }
3677
3678            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3679                    mHeavyWeightProcess.userId, 0));
3680            mHeavyWeightProcess = null;
3681        }
3682    }
3683
3684    @Override
3685    public void crashApplication(int uid, int initialPid, String packageName,
3686            String message) {
3687        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3688                != PackageManager.PERMISSION_GRANTED) {
3689            String msg = "Permission Denial: crashApplication() from pid="
3690                    + Binder.getCallingPid()
3691                    + ", uid=" + Binder.getCallingUid()
3692                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3693            Slog.w(TAG, msg);
3694            throw new SecurityException(msg);
3695        }
3696
3697        synchronized(this) {
3698            ProcessRecord proc = null;
3699
3700            // Figure out which process to kill.  We don't trust that initialPid
3701            // still has any relation to current pids, so must scan through the
3702            // list.
3703            synchronized (mPidsSelfLocked) {
3704                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3705                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3706                    if (p.uid != uid) {
3707                        continue;
3708                    }
3709                    if (p.pid == initialPid) {
3710                        proc = p;
3711                        break;
3712                    }
3713                    if (p.pkgList.containsKey(packageName)) {
3714                        proc = p;
3715                    }
3716                }
3717            }
3718
3719            if (proc == null) {
3720                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3721                        + " initialPid=" + initialPid
3722                        + " packageName=" + packageName);
3723                return;
3724            }
3725
3726            if (proc.thread != null) {
3727                if (proc.pid == Process.myPid()) {
3728                    Log.w(TAG, "crashApplication: trying to crash self!");
3729                    return;
3730                }
3731                long ident = Binder.clearCallingIdentity();
3732                try {
3733                    proc.thread.scheduleCrash(message);
3734                } catch (RemoteException e) {
3735                }
3736                Binder.restoreCallingIdentity(ident);
3737            }
3738        }
3739    }
3740
3741    @Override
3742    public final void finishSubActivity(IBinder token, String resultWho,
3743            int requestCode) {
3744        synchronized(this) {
3745            final long origId = Binder.clearCallingIdentity();
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r != null) {
3748                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3749            }
3750            Binder.restoreCallingIdentity(origId);
3751        }
3752    }
3753
3754    @Override
3755    public boolean finishActivityAffinity(IBinder token) {
3756        synchronized(this) {
3757            final long origId = Binder.clearCallingIdentity();
3758            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3759            boolean res = false;
3760            if (r != null) {
3761                res = r.task.stack.finishActivityAffinityLocked(r);
3762            }
3763            Binder.restoreCallingIdentity(origId);
3764            return res;
3765        }
3766    }
3767
3768    @Override
3769    public boolean willActivityBeVisible(IBinder token) {
3770        synchronized(this) {
3771            ActivityStack stack = ActivityRecord.getStackLocked(token);
3772            if (stack != null) {
3773                return stack.willActivityBeVisibleLocked(token);
3774            }
3775            return false;
3776        }
3777    }
3778
3779    @Override
3780    public void overridePendingTransition(IBinder token, String packageName,
3781            int enterAnim, int exitAnim) {
3782        synchronized(this) {
3783            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3784            if (self == null) {
3785                return;
3786            }
3787
3788            final long origId = Binder.clearCallingIdentity();
3789
3790            if (self.state == ActivityState.RESUMED
3791                    || self.state == ActivityState.PAUSING) {
3792                mWindowManager.overridePendingAppTransition(packageName,
3793                        enterAnim, exitAnim, null);
3794            }
3795
3796            Binder.restoreCallingIdentity(origId);
3797        }
3798    }
3799
3800    /**
3801     * Main function for removing an existing process from the activity manager
3802     * as a result of that process going away.  Clears out all connections
3803     * to the process.
3804     */
3805    private final void handleAppDiedLocked(ProcessRecord app,
3806            boolean restarting, boolean allowRestart) {
3807        int pid = app.pid;
3808        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3809        if (!restarting) {
3810            removeLruProcessLocked(app);
3811            if (pid > 0) {
3812                ProcessList.remove(pid);
3813            }
3814        }
3815
3816        if (mProfileProc == app) {
3817            clearProfilerLocked();
3818        }
3819
3820        // Remove this application's activities from active lists.
3821        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3822
3823        app.activities.clear();
3824
3825        if (app.instrumentationClass != null) {
3826            Slog.w(TAG, "Crash of app " + app.processName
3827                  + " running instrumentation " + app.instrumentationClass);
3828            Bundle info = new Bundle();
3829            info.putString("shortMsg", "Process crashed.");
3830            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3831        }
3832
3833        if (!restarting) {
3834            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3835                // If there was nothing to resume, and we are not already
3836                // restarting this process, but there is a visible activity that
3837                // is hosted by the process...  then make sure all visible
3838                // activities are running, taking care of restarting this
3839                // process.
3840                if (hasVisibleActivities) {
3841                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3842                }
3843            }
3844        }
3845    }
3846
3847    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3848        IBinder threadBinder = thread.asBinder();
3849        // Find the application record.
3850        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3851            ProcessRecord rec = mLruProcesses.get(i);
3852            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3853                return i;
3854            }
3855        }
3856        return -1;
3857    }
3858
3859    final ProcessRecord getRecordForAppLocked(
3860            IApplicationThread thread) {
3861        if (thread == null) {
3862            return null;
3863        }
3864
3865        int appIndex = getLRURecordIndexForAppLocked(thread);
3866        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3867    }
3868
3869    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3870        // If there are no longer any background processes running,
3871        // and the app that died was not running instrumentation,
3872        // then tell everyone we are now low on memory.
3873        boolean haveBg = false;
3874        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3875            ProcessRecord rec = mLruProcesses.get(i);
3876            if (rec.thread != null
3877                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3878                haveBg = true;
3879                break;
3880            }
3881        }
3882
3883        if (!haveBg) {
3884            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3885            if (doReport) {
3886                long now = SystemClock.uptimeMillis();
3887                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3888                    doReport = false;
3889                } else {
3890                    mLastMemUsageReportTime = now;
3891                }
3892            }
3893            final ArrayList<ProcessMemInfo> memInfos
3894                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3895            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3896            long now = SystemClock.uptimeMillis();
3897            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3898                ProcessRecord rec = mLruProcesses.get(i);
3899                if (rec == dyingProc || rec.thread == null) {
3900                    continue;
3901                }
3902                if (doReport) {
3903                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3904                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3905                }
3906                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3907                    // The low memory report is overriding any current
3908                    // state for a GC request.  Make sure to do
3909                    // heavy/important/visible/foreground processes first.
3910                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3911                        rec.lastRequestedGc = 0;
3912                    } else {
3913                        rec.lastRequestedGc = rec.lastLowMemory;
3914                    }
3915                    rec.reportLowMemory = true;
3916                    rec.lastLowMemory = now;
3917                    mProcessesToGc.remove(rec);
3918                    addProcessToGcListLocked(rec);
3919                }
3920            }
3921            if (doReport) {
3922                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3923                mHandler.sendMessage(msg);
3924            }
3925            scheduleAppGcsLocked();
3926        }
3927    }
3928
3929    final void appDiedLocked(ProcessRecord app, int pid,
3930            IApplicationThread thread) {
3931
3932        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3933        synchronized (stats) {
3934            stats.noteProcessDiedLocked(app.info.uid, pid);
3935        }
3936
3937        // Clean up already done if the process has been re-started.
3938        if (app.pid == pid && app.thread != null &&
3939                app.thread.asBinder() == thread.asBinder()) {
3940            boolean doLowMem = app.instrumentationClass == null;
3941            boolean doOomAdj = doLowMem;
3942            if (!app.killedByAm) {
3943                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3944                        + ") has died.");
3945                mAllowLowerMemLevel = true;
3946            } else {
3947                // Note that we always want to do oom adj to update our state with the
3948                // new number of procs.
3949                mAllowLowerMemLevel = false;
3950                doLowMem = false;
3951            }
3952            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3953            if (DEBUG_CLEANUP) Slog.v(
3954                TAG, "Dying app: " + app + ", pid: " + pid
3955                + ", thread: " + thread.asBinder());
3956            handleAppDiedLocked(app, false, true);
3957
3958            if (doOomAdj) {
3959                updateOomAdjLocked();
3960            }
3961            if (doLowMem) {
3962                doLowMemReportIfNeededLocked(app);
3963            }
3964        } else if (app.pid != pid) {
3965            // A new process has already been started.
3966            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3967                    + ") has died and restarted (pid " + app.pid + ").");
3968            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3969        } else if (DEBUG_PROCESSES) {
3970            Slog.d(TAG, "Received spurious death notification for thread "
3971                    + thread.asBinder());
3972        }
3973    }
3974
3975    /**
3976     * If a stack trace dump file is configured, dump process stack traces.
3977     * @param clearTraces causes the dump file to be erased prior to the new
3978     *    traces being written, if true; when false, the new traces will be
3979     *    appended to any existing file content.
3980     * @param firstPids of dalvik VM processes to dump stack traces for first
3981     * @param lastPids of dalvik VM processes to dump stack traces for last
3982     * @param nativeProcs optional list of native process names to dump stack crawls
3983     * @return file containing stack traces, or null if no dump file is configured
3984     */
3985    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3986            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3987        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3988        if (tracesPath == null || tracesPath.length() == 0) {
3989            return null;
3990        }
3991
3992        File tracesFile = new File(tracesPath);
3993        try {
3994            File tracesDir = tracesFile.getParentFile();
3995            if (!tracesDir.exists()) {
3996                tracesFile.mkdirs();
3997                if (!SELinux.restorecon(tracesDir)) {
3998                    return null;
3999                }
4000            }
4001            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4002
4003            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4004            tracesFile.createNewFile();
4005            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4006        } catch (IOException e) {
4007            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4008            return null;
4009        }
4010
4011        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4012        return tracesFile;
4013    }
4014
4015    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4016            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4017        // Use a FileObserver to detect when traces finish writing.
4018        // The order of traces is considered important to maintain for legibility.
4019        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4020            @Override
4021            public synchronized void onEvent(int event, String path) { notify(); }
4022        };
4023
4024        try {
4025            observer.startWatching();
4026
4027            // First collect all of the stacks of the most important pids.
4028            if (firstPids != null) {
4029                try {
4030                    int num = firstPids.size();
4031                    for (int i = 0; i < num; i++) {
4032                        synchronized (observer) {
4033                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4034                            observer.wait(200);  // Wait for write-close, give up after 200msec
4035                        }
4036                    }
4037                } catch (InterruptedException e) {
4038                    Log.wtf(TAG, e);
4039                }
4040            }
4041
4042            // Next collect the stacks of the native pids
4043            if (nativeProcs != null) {
4044                int[] pids = Process.getPidsForCommands(nativeProcs);
4045                if (pids != null) {
4046                    for (int pid : pids) {
4047                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4048                    }
4049                }
4050            }
4051
4052            // Lastly, measure CPU usage.
4053            if (processCpuTracker != null) {
4054                processCpuTracker.init();
4055                System.gc();
4056                processCpuTracker.update();
4057                try {
4058                    synchronized (processCpuTracker) {
4059                        processCpuTracker.wait(500); // measure over 1/2 second.
4060                    }
4061                } catch (InterruptedException e) {
4062                }
4063                processCpuTracker.update();
4064
4065                // We'll take the stack crawls of just the top apps using CPU.
4066                final int N = processCpuTracker.countWorkingStats();
4067                int numProcs = 0;
4068                for (int i=0; i<N && numProcs<5; i++) {
4069                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4070                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4071                        numProcs++;
4072                        try {
4073                            synchronized (observer) {
4074                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4075                                observer.wait(200);  // Wait for write-close, give up after 200msec
4076                            }
4077                        } catch (InterruptedException e) {
4078                            Log.wtf(TAG, e);
4079                        }
4080
4081                    }
4082                }
4083            }
4084        } finally {
4085            observer.stopWatching();
4086        }
4087    }
4088
4089    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4090        if (true || IS_USER_BUILD) {
4091            return;
4092        }
4093        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4094        if (tracesPath == null || tracesPath.length() == 0) {
4095            return;
4096        }
4097
4098        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4099        StrictMode.allowThreadDiskWrites();
4100        try {
4101            final File tracesFile = new File(tracesPath);
4102            final File tracesDir = tracesFile.getParentFile();
4103            final File tracesTmp = new File(tracesDir, "__tmp__");
4104            try {
4105                if (!tracesDir.exists()) {
4106                    tracesFile.mkdirs();
4107                    if (!SELinux.restorecon(tracesDir.getPath())) {
4108                        return;
4109                    }
4110                }
4111                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4112
4113                if (tracesFile.exists()) {
4114                    tracesTmp.delete();
4115                    tracesFile.renameTo(tracesTmp);
4116                }
4117                StringBuilder sb = new StringBuilder();
4118                Time tobj = new Time();
4119                tobj.set(System.currentTimeMillis());
4120                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4121                sb.append(": ");
4122                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4123                sb.append(" since ");
4124                sb.append(msg);
4125                FileOutputStream fos = new FileOutputStream(tracesFile);
4126                fos.write(sb.toString().getBytes());
4127                if (app == null) {
4128                    fos.write("\n*** No application process!".getBytes());
4129                }
4130                fos.close();
4131                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4132            } catch (IOException e) {
4133                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4134                return;
4135            }
4136
4137            if (app != null) {
4138                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4139                firstPids.add(app.pid);
4140                dumpStackTraces(tracesPath, firstPids, null, null, null);
4141            }
4142
4143            File lastTracesFile = null;
4144            File curTracesFile = null;
4145            for (int i=9; i>=0; i--) {
4146                String name = String.format(Locale.US, "slow%02d.txt", i);
4147                curTracesFile = new File(tracesDir, name);
4148                if (curTracesFile.exists()) {
4149                    if (lastTracesFile != null) {
4150                        curTracesFile.renameTo(lastTracesFile);
4151                    } else {
4152                        curTracesFile.delete();
4153                    }
4154                }
4155                lastTracesFile = curTracesFile;
4156            }
4157            tracesFile.renameTo(curTracesFile);
4158            if (tracesTmp.exists()) {
4159                tracesTmp.renameTo(tracesFile);
4160            }
4161        } finally {
4162            StrictMode.setThreadPolicy(oldPolicy);
4163        }
4164    }
4165
4166    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4167            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4168        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4169        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4170
4171        if (mController != null) {
4172            try {
4173                // 0 == continue, -1 = kill process immediately
4174                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4175                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4176            } catch (RemoteException e) {
4177                mController = null;
4178                Watchdog.getInstance().setActivityController(null);
4179            }
4180        }
4181
4182        long anrTime = SystemClock.uptimeMillis();
4183        if (MONITOR_CPU_USAGE) {
4184            updateCpuStatsNow();
4185        }
4186
4187        synchronized (this) {
4188            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4189            if (mShuttingDown) {
4190                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4191                return;
4192            } else if (app.notResponding) {
4193                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4194                return;
4195            } else if (app.crashing) {
4196                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4197                return;
4198            }
4199
4200            // In case we come through here for the same app before completing
4201            // this one, mark as anring now so we will bail out.
4202            app.notResponding = true;
4203
4204            // Log the ANR to the event log.
4205            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4206                    app.processName, app.info.flags, annotation);
4207
4208            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4209            firstPids.add(app.pid);
4210
4211            int parentPid = app.pid;
4212            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4213            if (parentPid != app.pid) firstPids.add(parentPid);
4214
4215            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4216
4217            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4218                ProcessRecord r = mLruProcesses.get(i);
4219                if (r != null && r.thread != null) {
4220                    int pid = r.pid;
4221                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4222                        if (r.persistent) {
4223                            firstPids.add(pid);
4224                        } else {
4225                            lastPids.put(pid, Boolean.TRUE);
4226                        }
4227                    }
4228                }
4229            }
4230        }
4231
4232        // Log the ANR to the main log.
4233        StringBuilder info = new StringBuilder();
4234        info.setLength(0);
4235        info.append("ANR in ").append(app.processName);
4236        if (activity != null && activity.shortComponentName != null) {
4237            info.append(" (").append(activity.shortComponentName).append(")");
4238        }
4239        info.append("\n");
4240        info.append("PID: ").append(app.pid).append("\n");
4241        if (annotation != null) {
4242            info.append("Reason: ").append(annotation).append("\n");
4243        }
4244        if (parent != null && parent != activity) {
4245            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4246        }
4247
4248        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4249
4250        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4251                NATIVE_STACKS_OF_INTEREST);
4252
4253        String cpuInfo = null;
4254        if (MONITOR_CPU_USAGE) {
4255            updateCpuStatsNow();
4256            synchronized (mProcessCpuThread) {
4257                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4258            }
4259            info.append(processCpuTracker.printCurrentLoad());
4260            info.append(cpuInfo);
4261        }
4262
4263        info.append(processCpuTracker.printCurrentState(anrTime));
4264
4265        Slog.e(TAG, info.toString());
4266        if (tracesFile == null) {
4267            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4268            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4269        }
4270
4271        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4272                cpuInfo, tracesFile, null);
4273
4274        if (mController != null) {
4275            try {
4276                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4277                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4278                if (res != 0) {
4279                    if (res < 0 && app.pid != MY_PID) {
4280                        Process.killProcess(app.pid);
4281                    } else {
4282                        synchronized (this) {
4283                            mServices.scheduleServiceTimeoutLocked(app);
4284                        }
4285                    }
4286                    return;
4287                }
4288            } catch (RemoteException e) {
4289                mController = null;
4290                Watchdog.getInstance().setActivityController(null);
4291            }
4292        }
4293
4294        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4295        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4296                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4297
4298        synchronized (this) {
4299            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4300                killUnneededProcessLocked(app, "background ANR");
4301                return;
4302            }
4303
4304            // Set the app's notResponding state, and look up the errorReportReceiver
4305            makeAppNotRespondingLocked(app,
4306                    activity != null ? activity.shortComponentName : null,
4307                    annotation != null ? "ANR " + annotation : "ANR",
4308                    info.toString());
4309
4310            // Bring up the infamous App Not Responding dialog
4311            Message msg = Message.obtain();
4312            HashMap<String, Object> map = new HashMap<String, Object>();
4313            msg.what = SHOW_NOT_RESPONDING_MSG;
4314            msg.obj = map;
4315            msg.arg1 = aboveSystem ? 1 : 0;
4316            map.put("app", app);
4317            if (activity != null) {
4318                map.put("activity", activity);
4319            }
4320
4321            mHandler.sendMessage(msg);
4322        }
4323    }
4324
4325    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4326        if (!mLaunchWarningShown) {
4327            mLaunchWarningShown = true;
4328            mHandler.post(new Runnable() {
4329                @Override
4330                public void run() {
4331                    synchronized (ActivityManagerService.this) {
4332                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4333                        d.show();
4334                        mHandler.postDelayed(new Runnable() {
4335                            @Override
4336                            public void run() {
4337                                synchronized (ActivityManagerService.this) {
4338                                    d.dismiss();
4339                                    mLaunchWarningShown = false;
4340                                }
4341                            }
4342                        }, 4000);
4343                    }
4344                }
4345            });
4346        }
4347    }
4348
4349    @Override
4350    public boolean clearApplicationUserData(final String packageName,
4351            final IPackageDataObserver observer, int userId) {
4352        enforceNotIsolatedCaller("clearApplicationUserData");
4353        int uid = Binder.getCallingUid();
4354        int pid = Binder.getCallingPid();
4355        userId = handleIncomingUser(pid, uid,
4356                userId, false, true, "clearApplicationUserData", null);
4357        long callingId = Binder.clearCallingIdentity();
4358        try {
4359            IPackageManager pm = AppGlobals.getPackageManager();
4360            int pkgUid = -1;
4361            synchronized(this) {
4362                try {
4363                    pkgUid = pm.getPackageUid(packageName, userId);
4364                } catch (RemoteException e) {
4365                }
4366                if (pkgUid == -1) {
4367                    Slog.w(TAG, "Invalid packageName: " + packageName);
4368                    if (observer != null) {
4369                        try {
4370                            observer.onRemoveCompleted(packageName, false);
4371                        } catch (RemoteException e) {
4372                            Slog.i(TAG, "Observer no longer exists.");
4373                        }
4374                    }
4375                    return false;
4376                }
4377                if (uid == pkgUid || checkComponentPermission(
4378                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4379                        pid, uid, -1, true)
4380                        == PackageManager.PERMISSION_GRANTED) {
4381                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4382                } else {
4383                    throw new SecurityException("PID " + pid + " does not have permission "
4384                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4385                                    + " of package " + packageName);
4386                }
4387            }
4388
4389            try {
4390                // Clear application user data
4391                pm.clearApplicationUserData(packageName, observer, userId);
4392
4393                // Remove all permissions granted from/to this package
4394                removeUriPermissionsForPackageLocked(packageName, userId, true);
4395
4396                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4397                        Uri.fromParts("package", packageName, null));
4398                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4399                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4400                        null, null, 0, null, null, null, false, false, userId);
4401            } catch (RemoteException e) {
4402            }
4403        } finally {
4404            Binder.restoreCallingIdentity(callingId);
4405        }
4406        return true;
4407    }
4408
4409    @Override
4410    public void killBackgroundProcesses(final String packageName, int userId) {
4411        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4412                != PackageManager.PERMISSION_GRANTED &&
4413                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4414                        != PackageManager.PERMISSION_GRANTED) {
4415            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4416                    + Binder.getCallingPid()
4417                    + ", uid=" + Binder.getCallingUid()
4418                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4419            Slog.w(TAG, msg);
4420            throw new SecurityException(msg);
4421        }
4422
4423        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4424                userId, true, true, "killBackgroundProcesses", null);
4425        long callingId = Binder.clearCallingIdentity();
4426        try {
4427            IPackageManager pm = AppGlobals.getPackageManager();
4428            synchronized(this) {
4429                int appId = -1;
4430                try {
4431                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4432                } catch (RemoteException e) {
4433                }
4434                if (appId == -1) {
4435                    Slog.w(TAG, "Invalid packageName: " + packageName);
4436                    return;
4437                }
4438                killPackageProcessesLocked(packageName, appId, userId,
4439                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4440            }
4441        } finally {
4442            Binder.restoreCallingIdentity(callingId);
4443        }
4444    }
4445
4446    @Override
4447    public void killAllBackgroundProcesses() {
4448        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4449                != PackageManager.PERMISSION_GRANTED) {
4450            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4451                    + Binder.getCallingPid()
4452                    + ", uid=" + Binder.getCallingUid()
4453                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4454            Slog.w(TAG, msg);
4455            throw new SecurityException(msg);
4456        }
4457
4458        long callingId = Binder.clearCallingIdentity();
4459        try {
4460            synchronized(this) {
4461                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4462                final int NP = mProcessNames.getMap().size();
4463                for (int ip=0; ip<NP; ip++) {
4464                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4465                    final int NA = apps.size();
4466                    for (int ia=0; ia<NA; ia++) {
4467                        ProcessRecord app = apps.valueAt(ia);
4468                        if (app.persistent) {
4469                            // we don't kill persistent processes
4470                            continue;
4471                        }
4472                        if (app.removed) {
4473                            procs.add(app);
4474                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4475                            app.removed = true;
4476                            procs.add(app);
4477                        }
4478                    }
4479                }
4480
4481                int N = procs.size();
4482                for (int i=0; i<N; i++) {
4483                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4484                }
4485                mAllowLowerMemLevel = true;
4486                updateOomAdjLocked();
4487                doLowMemReportIfNeededLocked(null);
4488            }
4489        } finally {
4490            Binder.restoreCallingIdentity(callingId);
4491        }
4492    }
4493
4494    @Override
4495    public void forceStopPackage(final String packageName, int userId) {
4496        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4497                != PackageManager.PERMISSION_GRANTED) {
4498            String msg = "Permission Denial: forceStopPackage() from pid="
4499                    + Binder.getCallingPid()
4500                    + ", uid=" + Binder.getCallingUid()
4501                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4502            Slog.w(TAG, msg);
4503            throw new SecurityException(msg);
4504        }
4505        final int callingPid = Binder.getCallingPid();
4506        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4507                userId, true, true, "forceStopPackage", null);
4508        long callingId = Binder.clearCallingIdentity();
4509        try {
4510            IPackageManager pm = AppGlobals.getPackageManager();
4511            synchronized(this) {
4512                int[] users = userId == UserHandle.USER_ALL
4513                        ? getUsersLocked() : new int[] { userId };
4514                for (int user : users) {
4515                    int pkgUid = -1;
4516                    try {
4517                        pkgUid = pm.getPackageUid(packageName, user);
4518                    } catch (RemoteException e) {
4519                    }
4520                    if (pkgUid == -1) {
4521                        Slog.w(TAG, "Invalid packageName: " + packageName);
4522                        continue;
4523                    }
4524                    try {
4525                        pm.setPackageStoppedState(packageName, true, user);
4526                    } catch (RemoteException e) {
4527                    } catch (IllegalArgumentException e) {
4528                        Slog.w(TAG, "Failed trying to unstop package "
4529                                + packageName + ": " + e);
4530                    }
4531                    if (isUserRunningLocked(user, false)) {
4532                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4533                    }
4534                }
4535            }
4536        } finally {
4537            Binder.restoreCallingIdentity(callingId);
4538        }
4539    }
4540
4541    /*
4542     * The pkg name and app id have to be specified.
4543     */
4544    @Override
4545    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4546        if (pkg == null) {
4547            return;
4548        }
4549        // Make sure the uid is valid.
4550        if (appid < 0) {
4551            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4552            return;
4553        }
4554        int callerUid = Binder.getCallingUid();
4555        // Only the system server can kill an application
4556        if (callerUid == Process.SYSTEM_UID) {
4557            // Post an aysnc message to kill the application
4558            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4559            msg.arg1 = appid;
4560            msg.arg2 = 0;
4561            Bundle bundle = new Bundle();
4562            bundle.putString("pkg", pkg);
4563            bundle.putString("reason", reason);
4564            msg.obj = bundle;
4565            mHandler.sendMessage(msg);
4566        } else {
4567            throw new SecurityException(callerUid + " cannot kill pkg: " +
4568                    pkg);
4569        }
4570    }
4571
4572    @Override
4573    public void closeSystemDialogs(String reason) {
4574        enforceNotIsolatedCaller("closeSystemDialogs");
4575
4576        final int pid = Binder.getCallingPid();
4577        final int uid = Binder.getCallingUid();
4578        final long origId = Binder.clearCallingIdentity();
4579        try {
4580            synchronized (this) {
4581                // Only allow this from foreground processes, so that background
4582                // applications can't abuse it to prevent system UI from being shown.
4583                if (uid >= Process.FIRST_APPLICATION_UID) {
4584                    ProcessRecord proc;
4585                    synchronized (mPidsSelfLocked) {
4586                        proc = mPidsSelfLocked.get(pid);
4587                    }
4588                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4589                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4590                                + " from background process " + proc);
4591                        return;
4592                    }
4593                }
4594                closeSystemDialogsLocked(reason);
4595            }
4596        } finally {
4597            Binder.restoreCallingIdentity(origId);
4598        }
4599    }
4600
4601    void closeSystemDialogsLocked(String reason) {
4602        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4603        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4604                | Intent.FLAG_RECEIVER_FOREGROUND);
4605        if (reason != null) {
4606            intent.putExtra("reason", reason);
4607        }
4608        mWindowManager.closeSystemDialogs(reason);
4609
4610        mStackSupervisor.closeSystemDialogsLocked();
4611
4612        broadcastIntentLocked(null, null, intent, null,
4613                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4614                Process.SYSTEM_UID, UserHandle.USER_ALL);
4615    }
4616
4617    @Override
4618    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4619        enforceNotIsolatedCaller("getProcessMemoryInfo");
4620        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4621        for (int i=pids.length-1; i>=0; i--) {
4622            ProcessRecord proc;
4623            int oomAdj;
4624            synchronized (this) {
4625                synchronized (mPidsSelfLocked) {
4626                    proc = mPidsSelfLocked.get(pids[i]);
4627                    oomAdj = proc != null ? proc.setAdj : 0;
4628                }
4629            }
4630            infos[i] = new Debug.MemoryInfo();
4631            Debug.getMemoryInfo(pids[i], infos[i]);
4632            if (proc != null) {
4633                synchronized (this) {
4634                    if (proc.thread != null && proc.setAdj == oomAdj) {
4635                        // Record this for posterity if the process has been stable.
4636                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4637                                infos[i].getTotalUss(), false, proc.pkgList);
4638                    }
4639                }
4640            }
4641        }
4642        return infos;
4643    }
4644
4645    @Override
4646    public long[] getProcessPss(int[] pids) {
4647        enforceNotIsolatedCaller("getProcessPss");
4648        long[] pss = new long[pids.length];
4649        for (int i=pids.length-1; i>=0; i--) {
4650            ProcessRecord proc;
4651            int oomAdj;
4652            synchronized (this) {
4653                synchronized (mPidsSelfLocked) {
4654                    proc = mPidsSelfLocked.get(pids[i]);
4655                    oomAdj = proc != null ? proc.setAdj : 0;
4656                }
4657            }
4658            long[] tmpUss = new long[1];
4659            pss[i] = Debug.getPss(pids[i], tmpUss);
4660            if (proc != null) {
4661                synchronized (this) {
4662                    if (proc.thread != null && proc.setAdj == oomAdj) {
4663                        // Record this for posterity if the process has been stable.
4664                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4665                    }
4666                }
4667            }
4668        }
4669        return pss;
4670    }
4671
4672    @Override
4673    public void killApplicationProcess(String processName, int uid) {
4674        if (processName == null) {
4675            return;
4676        }
4677
4678        int callerUid = Binder.getCallingUid();
4679        // Only the system server can kill an application
4680        if (callerUid == Process.SYSTEM_UID) {
4681            synchronized (this) {
4682                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4683                if (app != null && app.thread != null) {
4684                    try {
4685                        app.thread.scheduleSuicide();
4686                    } catch (RemoteException e) {
4687                        // If the other end already died, then our work here is done.
4688                    }
4689                } else {
4690                    Slog.w(TAG, "Process/uid not found attempting kill of "
4691                            + processName + " / " + uid);
4692                }
4693            }
4694        } else {
4695            throw new SecurityException(callerUid + " cannot kill app process: " +
4696                    processName);
4697        }
4698    }
4699
4700    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4701        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4702                false, true, false, false, UserHandle.getUserId(uid), reason);
4703        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4704                Uri.fromParts("package", packageName, null));
4705        if (!mProcessesReady) {
4706            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4707                    | Intent.FLAG_RECEIVER_FOREGROUND);
4708        }
4709        intent.putExtra(Intent.EXTRA_UID, uid);
4710        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4711        broadcastIntentLocked(null, null, intent,
4712                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4713                false, false,
4714                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4715    }
4716
4717    private void forceStopUserLocked(int userId, String reason) {
4718        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4719        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4720        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4721                | Intent.FLAG_RECEIVER_FOREGROUND);
4722        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4723        broadcastIntentLocked(null, null, intent,
4724                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4725                false, false,
4726                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4727    }
4728
4729    private final boolean killPackageProcessesLocked(String packageName, int appId,
4730            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4731            boolean doit, boolean evenPersistent, String reason) {
4732        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4733
4734        // Remove all processes this package may have touched: all with the
4735        // same UID (except for the system or root user), and all whose name
4736        // matches the package name.
4737        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4738        final int NP = mProcessNames.getMap().size();
4739        for (int ip=0; ip<NP; ip++) {
4740            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4741            final int NA = apps.size();
4742            for (int ia=0; ia<NA; ia++) {
4743                ProcessRecord app = apps.valueAt(ia);
4744                if (app.persistent && !evenPersistent) {
4745                    // we don't kill persistent processes
4746                    continue;
4747                }
4748                if (app.removed) {
4749                    if (doit) {
4750                        procs.add(app);
4751                    }
4752                    continue;
4753                }
4754
4755                // Skip process if it doesn't meet our oom adj requirement.
4756                if (app.setAdj < minOomAdj) {
4757                    continue;
4758                }
4759
4760                // If no package is specified, we call all processes under the
4761                // give user id.
4762                if (packageName == null) {
4763                    if (app.userId != userId) {
4764                        continue;
4765                    }
4766                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4767                        continue;
4768                    }
4769                // Package has been specified, we want to hit all processes
4770                // that match it.  We need to qualify this by the processes
4771                // that are running under the specified app and user ID.
4772                } else {
4773                    if (UserHandle.getAppId(app.uid) != appId) {
4774                        continue;
4775                    }
4776                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4777                        continue;
4778                    }
4779                    if (!app.pkgList.containsKey(packageName)) {
4780                        continue;
4781                    }
4782                }
4783
4784                // Process has passed all conditions, kill it!
4785                if (!doit) {
4786                    return true;
4787                }
4788                app.removed = true;
4789                procs.add(app);
4790            }
4791        }
4792
4793        int N = procs.size();
4794        for (int i=0; i<N; i++) {
4795            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4796        }
4797        updateOomAdjLocked();
4798        return N > 0;
4799    }
4800
4801    private final boolean forceStopPackageLocked(String name, int appId,
4802            boolean callerWillRestart, boolean purgeCache, boolean doit,
4803            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4804        int i;
4805        int N;
4806
4807        if (userId == UserHandle.USER_ALL && name == null) {
4808            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4809        }
4810
4811        if (appId < 0 && name != null) {
4812            try {
4813                appId = UserHandle.getAppId(
4814                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4815            } catch (RemoteException e) {
4816            }
4817        }
4818
4819        if (doit) {
4820            if (name != null) {
4821                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4822                        + " user=" + userId + ": " + reason);
4823            } else {
4824                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4825            }
4826
4827            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4828            for (int ip=pmap.size()-1; ip>=0; ip--) {
4829                SparseArray<Long> ba = pmap.valueAt(ip);
4830                for (i=ba.size()-1; i>=0; i--) {
4831                    boolean remove = false;
4832                    final int entUid = ba.keyAt(i);
4833                    if (name != null) {
4834                        if (userId == UserHandle.USER_ALL) {
4835                            if (UserHandle.getAppId(entUid) == appId) {
4836                                remove = true;
4837                            }
4838                        } else {
4839                            if (entUid == UserHandle.getUid(userId, appId)) {
4840                                remove = true;
4841                            }
4842                        }
4843                    } else if (UserHandle.getUserId(entUid) == userId) {
4844                        remove = true;
4845                    }
4846                    if (remove) {
4847                        ba.removeAt(i);
4848                    }
4849                }
4850                if (ba.size() == 0) {
4851                    pmap.removeAt(ip);
4852                }
4853            }
4854        }
4855
4856        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4857                -100, callerWillRestart, true, doit, evenPersistent,
4858                name == null ? ("stop user " + userId) : ("stop " + name));
4859
4860        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4861            if (!doit) {
4862                return true;
4863            }
4864            didSomething = true;
4865        }
4866
4867        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4868            if (!doit) {
4869                return true;
4870            }
4871            didSomething = true;
4872        }
4873
4874        if (name == null) {
4875            // Remove all sticky broadcasts from this user.
4876            mStickyBroadcasts.remove(userId);
4877        }
4878
4879        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4880        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4881                userId, providers)) {
4882            if (!doit) {
4883                return true;
4884            }
4885            didSomething = true;
4886        }
4887        N = providers.size();
4888        for (i=0; i<N; i++) {
4889            removeDyingProviderLocked(null, providers.get(i), true);
4890        }
4891
4892        // Remove transient permissions granted from/to this package/user
4893        removeUriPermissionsForPackageLocked(name, userId, false);
4894
4895        if (name == null || uninstalling) {
4896            // Remove pending intents.  For now we only do this when force
4897            // stopping users, because we have some problems when doing this
4898            // for packages -- app widgets are not currently cleaned up for
4899            // such packages, so they can be left with bad pending intents.
4900            if (mIntentSenderRecords.size() > 0) {
4901                Iterator<WeakReference<PendingIntentRecord>> it
4902                        = mIntentSenderRecords.values().iterator();
4903                while (it.hasNext()) {
4904                    WeakReference<PendingIntentRecord> wpir = it.next();
4905                    if (wpir == null) {
4906                        it.remove();
4907                        continue;
4908                    }
4909                    PendingIntentRecord pir = wpir.get();
4910                    if (pir == null) {
4911                        it.remove();
4912                        continue;
4913                    }
4914                    if (name == null) {
4915                        // Stopping user, remove all objects for the user.
4916                        if (pir.key.userId != userId) {
4917                            // Not the same user, skip it.
4918                            continue;
4919                        }
4920                    } else {
4921                        if (UserHandle.getAppId(pir.uid) != appId) {
4922                            // Different app id, skip it.
4923                            continue;
4924                        }
4925                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4926                            // Different user, skip it.
4927                            continue;
4928                        }
4929                        if (!pir.key.packageName.equals(name)) {
4930                            // Different package, skip it.
4931                            continue;
4932                        }
4933                    }
4934                    if (!doit) {
4935                        return true;
4936                    }
4937                    didSomething = true;
4938                    it.remove();
4939                    pir.canceled = true;
4940                    if (pir.key.activity != null) {
4941                        pir.key.activity.pendingResults.remove(pir.ref);
4942                    }
4943                }
4944            }
4945        }
4946
4947        if (doit) {
4948            if (purgeCache && name != null) {
4949                AttributeCache ac = AttributeCache.instance();
4950                if (ac != null) {
4951                    ac.removePackage(name);
4952                }
4953            }
4954            if (mBooted) {
4955                mStackSupervisor.resumeTopActivitiesLocked();
4956                mStackSupervisor.scheduleIdleLocked();
4957            }
4958        }
4959
4960        return didSomething;
4961    }
4962
4963    private final boolean removeProcessLocked(ProcessRecord app,
4964            boolean callerWillRestart, boolean allowRestart, String reason) {
4965        final String name = app.processName;
4966        final int uid = app.uid;
4967        if (DEBUG_PROCESSES) Slog.d(
4968            TAG, "Force removing proc " + app.toShortString() + " (" + name
4969            + "/" + uid + ")");
4970
4971        mProcessNames.remove(name, uid);
4972        mIsolatedProcesses.remove(app.uid);
4973        if (mHeavyWeightProcess == app) {
4974            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4975                    mHeavyWeightProcess.userId, 0));
4976            mHeavyWeightProcess = null;
4977        }
4978        boolean needRestart = false;
4979        if (app.pid > 0 && app.pid != MY_PID) {
4980            int pid = app.pid;
4981            synchronized (mPidsSelfLocked) {
4982                mPidsSelfLocked.remove(pid);
4983                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4984            }
4985            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4986                    app.processName, app.info.uid);
4987            if (app.isolated) {
4988                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4989            }
4990            killUnneededProcessLocked(app, reason);
4991            handleAppDiedLocked(app, true, allowRestart);
4992            removeLruProcessLocked(app);
4993
4994            if (app.persistent && !app.isolated) {
4995                if (!callerWillRestart) {
4996                    addAppLocked(app.info, false);
4997                } else {
4998                    needRestart = true;
4999                }
5000            }
5001        } else {
5002            mRemovedProcesses.add(app);
5003        }
5004
5005        return needRestart;
5006    }
5007
5008    private final void processStartTimedOutLocked(ProcessRecord app) {
5009        final int pid = app.pid;
5010        boolean gone = false;
5011        synchronized (mPidsSelfLocked) {
5012            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5013            if (knownApp != null && knownApp.thread == null) {
5014                mPidsSelfLocked.remove(pid);
5015                gone = true;
5016            }
5017        }
5018
5019        if (gone) {
5020            Slog.w(TAG, "Process " + app + " failed to attach");
5021            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5022                    pid, app.uid, app.processName);
5023            mProcessNames.remove(app.processName, app.uid);
5024            mIsolatedProcesses.remove(app.uid);
5025            if (mHeavyWeightProcess == app) {
5026                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5027                        mHeavyWeightProcess.userId, 0));
5028                mHeavyWeightProcess = null;
5029            }
5030            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5031                    app.processName, app.info.uid);
5032            if (app.isolated) {
5033                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5034            }
5035            // Take care of any launching providers waiting for this process.
5036            checkAppInLaunchingProvidersLocked(app, true);
5037            // Take care of any services that are waiting for the process.
5038            mServices.processStartTimedOutLocked(app);
5039            killUnneededProcessLocked(app, "start timeout");
5040            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5041                Slog.w(TAG, "Unattached app died before backup, skipping");
5042                try {
5043                    IBackupManager bm = IBackupManager.Stub.asInterface(
5044                            ServiceManager.getService(Context.BACKUP_SERVICE));
5045                    bm.agentDisconnected(app.info.packageName);
5046                } catch (RemoteException e) {
5047                    // Can't happen; the backup manager is local
5048                }
5049            }
5050            if (isPendingBroadcastProcessLocked(pid)) {
5051                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5052                skipPendingBroadcastLocked(pid);
5053            }
5054        } else {
5055            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5056        }
5057    }
5058
5059    private final boolean attachApplicationLocked(IApplicationThread thread,
5060            int pid) {
5061
5062        // Find the application record that is being attached...  either via
5063        // the pid if we are running in multiple processes, or just pull the
5064        // next app record if we are emulating process with anonymous threads.
5065        ProcessRecord app;
5066        if (pid != MY_PID && pid >= 0) {
5067            synchronized (mPidsSelfLocked) {
5068                app = mPidsSelfLocked.get(pid);
5069            }
5070        } else {
5071            app = null;
5072        }
5073
5074        if (app == null) {
5075            Slog.w(TAG, "No pending application record for pid " + pid
5076                    + " (IApplicationThread " + thread + "); dropping process");
5077            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5078            if (pid > 0 && pid != MY_PID) {
5079                Process.killProcessQuiet(pid);
5080            } else {
5081                try {
5082                    thread.scheduleExit();
5083                } catch (Exception e) {
5084                    // Ignore exceptions.
5085                }
5086            }
5087            return false;
5088        }
5089
5090        // If this application record is still attached to a previous
5091        // process, clean it up now.
5092        if (app.thread != null) {
5093            handleAppDiedLocked(app, true, true);
5094        }
5095
5096        // Tell the process all about itself.
5097
5098        if (localLOGV) Slog.v(
5099                TAG, "Binding process pid " + pid + " to record " + app);
5100
5101        final String processName = app.processName;
5102        try {
5103            AppDeathRecipient adr = new AppDeathRecipient(
5104                    app, pid, thread);
5105            thread.asBinder().linkToDeath(adr, 0);
5106            app.deathRecipient = adr;
5107        } catch (RemoteException e) {
5108            app.resetPackageList(mProcessStats);
5109            startProcessLocked(app, "link fail", processName);
5110            return false;
5111        }
5112
5113        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5114
5115        app.makeActive(thread, mProcessStats);
5116        app.curAdj = app.setAdj = -100;
5117        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5118        app.forcingToForeground = null;
5119        updateProcessForegroundLocked(app, false, false);
5120        app.hasShownUi = false;
5121        app.debugging = false;
5122        app.cached = false;
5123
5124        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5125
5126        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5127        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5128
5129        if (!normalMode) {
5130            Slog.i(TAG, "Launching preboot mode app: " + app);
5131        }
5132
5133        if (localLOGV) Slog.v(
5134            TAG, "New app record " + app
5135            + " thread=" + thread.asBinder() + " pid=" + pid);
5136        try {
5137            int testMode = IApplicationThread.DEBUG_OFF;
5138            if (mDebugApp != null && mDebugApp.equals(processName)) {
5139                testMode = mWaitForDebugger
5140                    ? IApplicationThread.DEBUG_WAIT
5141                    : IApplicationThread.DEBUG_ON;
5142                app.debugging = true;
5143                if (mDebugTransient) {
5144                    mDebugApp = mOrigDebugApp;
5145                    mWaitForDebugger = mOrigWaitForDebugger;
5146                }
5147            }
5148            String profileFile = app.instrumentationProfileFile;
5149            ParcelFileDescriptor profileFd = null;
5150            boolean profileAutoStop = false;
5151            if (mProfileApp != null && mProfileApp.equals(processName)) {
5152                mProfileProc = app;
5153                profileFile = mProfileFile;
5154                profileFd = mProfileFd;
5155                profileAutoStop = mAutoStopProfiler;
5156            }
5157            boolean enableOpenGlTrace = false;
5158            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5159                enableOpenGlTrace = true;
5160                mOpenGlTraceApp = null;
5161            }
5162
5163            // If the app is being launched for restore or full backup, set it up specially
5164            boolean isRestrictedBackupMode = false;
5165            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5166                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5167                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5168                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5169            }
5170
5171            ensurePackageDexOpt(app.instrumentationInfo != null
5172                    ? app.instrumentationInfo.packageName
5173                    : app.info.packageName);
5174            if (app.instrumentationClass != null) {
5175                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5176            }
5177            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5178                    + processName + " with config " + mConfiguration);
5179            ApplicationInfo appInfo = app.instrumentationInfo != null
5180                    ? app.instrumentationInfo : app.info;
5181            app.compat = compatibilityInfoForPackageLocked(appInfo);
5182            if (profileFd != null) {
5183                profileFd = profileFd.dup();
5184            }
5185            thread.bindApplication(processName, appInfo, providers,
5186                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5187                    app.instrumentationArguments, app.instrumentationWatcher,
5188                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5189                    isRestrictedBackupMode || !normalMode, app.persistent,
5190                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5191                    mCoreSettingsObserver.getCoreSettingsLocked());
5192            updateLruProcessLocked(app, false, null);
5193            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5194        } catch (Exception e) {
5195            // todo: Yikes!  What should we do?  For now we will try to
5196            // start another process, but that could easily get us in
5197            // an infinite loop of restarting processes...
5198            Slog.w(TAG, "Exception thrown during bind!", e);
5199
5200            app.resetPackageList(mProcessStats);
5201            app.unlinkDeathRecipient();
5202            startProcessLocked(app, "bind fail", processName);
5203            return false;
5204        }
5205
5206        // Remove this record from the list of starting applications.
5207        mPersistentStartingProcesses.remove(app);
5208        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5209                "Attach application locked removing on hold: " + app);
5210        mProcessesOnHold.remove(app);
5211
5212        boolean badApp = false;
5213        boolean didSomething = false;
5214
5215        // See if the top visible activity is waiting to run in this process...
5216        if (normalMode) {
5217            try {
5218                if (mStackSupervisor.attachApplicationLocked(app)) {
5219                    didSomething = true;
5220                }
5221            } catch (Exception e) {
5222                badApp = true;
5223            }
5224        }
5225
5226        // Find any services that should be running in this process...
5227        if (!badApp) {
5228            try {
5229                didSomething |= mServices.attachApplicationLocked(app, processName);
5230            } catch (Exception e) {
5231                badApp = true;
5232            }
5233        }
5234
5235        // Check if a next-broadcast receiver is in this process...
5236        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5237            try {
5238                didSomething |= sendPendingBroadcastsLocked(app);
5239            } catch (Exception e) {
5240                // If the app died trying to launch the receiver we declare it 'bad'
5241                badApp = true;
5242            }
5243        }
5244
5245        // Check whether the next backup agent is in this process...
5246        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5247            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5248            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5249            try {
5250                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5251                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5252                        mBackupTarget.backupMode);
5253            } catch (Exception e) {
5254                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5255                e.printStackTrace();
5256            }
5257        }
5258
5259        if (badApp) {
5260            // todo: Also need to kill application to deal with all
5261            // kinds of exceptions.
5262            handleAppDiedLocked(app, false, true);
5263            return false;
5264        }
5265
5266        if (!didSomething) {
5267            updateOomAdjLocked();
5268        }
5269
5270        return true;
5271    }
5272
5273    @Override
5274    public final void attachApplication(IApplicationThread thread) {
5275        synchronized (this) {
5276            int callingPid = Binder.getCallingPid();
5277            final long origId = Binder.clearCallingIdentity();
5278            attachApplicationLocked(thread, callingPid);
5279            Binder.restoreCallingIdentity(origId);
5280        }
5281    }
5282
5283    @Override
5284    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5285        final long origId = Binder.clearCallingIdentity();
5286        synchronized (this) {
5287            ActivityStack stack = ActivityRecord.getStackLocked(token);
5288            if (stack != null) {
5289                ActivityRecord r =
5290                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5291                if (stopProfiling) {
5292                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5293                        try {
5294                            mProfileFd.close();
5295                        } catch (IOException e) {
5296                        }
5297                        clearProfilerLocked();
5298                    }
5299                }
5300            }
5301        }
5302        Binder.restoreCallingIdentity(origId);
5303    }
5304
5305    void enableScreenAfterBoot() {
5306        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5307                SystemClock.uptimeMillis());
5308        mWindowManager.enableScreenAfterBoot();
5309
5310        synchronized (this) {
5311            updateEventDispatchingLocked();
5312        }
5313    }
5314
5315    @Override
5316    public void showBootMessage(final CharSequence msg, final boolean always) {
5317        enforceNotIsolatedCaller("showBootMessage");
5318        mWindowManager.showBootMessage(msg, always);
5319    }
5320
5321    @Override
5322    public void dismissKeyguardOnNextActivity() {
5323        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5324        final long token = Binder.clearCallingIdentity();
5325        try {
5326            synchronized (this) {
5327                if (DEBUG_LOCKSCREEN) logLockScreen("");
5328                if (mLockScreenShown) {
5329                    mLockScreenShown = false;
5330                    comeOutOfSleepIfNeededLocked();
5331                }
5332                mStackSupervisor.setDismissKeyguard(true);
5333            }
5334        } finally {
5335            Binder.restoreCallingIdentity(token);
5336        }
5337    }
5338
5339    final void finishBooting() {
5340        // Register receivers to handle package update events
5341        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5342
5343        synchronized (this) {
5344            // Ensure that any processes we had put on hold are now started
5345            // up.
5346            final int NP = mProcessesOnHold.size();
5347            if (NP > 0) {
5348                ArrayList<ProcessRecord> procs =
5349                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5350                for (int ip=0; ip<NP; ip++) {
5351                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5352                            + procs.get(ip));
5353                    startProcessLocked(procs.get(ip), "on-hold", null);
5354                }
5355            }
5356
5357            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5358                // Start looking for apps that are abusing wake locks.
5359                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5360                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5361                // Tell anyone interested that we are done booting!
5362                SystemProperties.set("sys.boot_completed", "1");
5363                SystemProperties.set("dev.bootcomplete", "1");
5364                for (int i=0; i<mStartedUsers.size(); i++) {
5365                    UserStartedState uss = mStartedUsers.valueAt(i);
5366                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5367                        uss.mState = UserStartedState.STATE_RUNNING;
5368                        final int userId = mStartedUsers.keyAt(i);
5369                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5370                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5371                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5372                        broadcastIntentLocked(null, null, intent, null,
5373                                new IIntentReceiver.Stub() {
5374                                    @Override
5375                                    public void performReceive(Intent intent, int resultCode,
5376                                            String data, Bundle extras, boolean ordered,
5377                                            boolean sticky, int sendingUser) {
5378                                        synchronized (ActivityManagerService.this) {
5379                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5380                                                    true, false);
5381                                        }
5382                                    }
5383                                },
5384                                0, null, null,
5385                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5386                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5387                                userId);
5388                    }
5389                }
5390                scheduleStartProfilesLocked();
5391            }
5392        }
5393    }
5394
5395    final void ensureBootCompleted() {
5396        boolean booting;
5397        boolean enableScreen;
5398        synchronized (this) {
5399            booting = mBooting;
5400            mBooting = false;
5401            enableScreen = !mBooted;
5402            mBooted = true;
5403        }
5404
5405        if (booting) {
5406            finishBooting();
5407        }
5408
5409        if (enableScreen) {
5410            enableScreenAfterBoot();
5411        }
5412    }
5413
5414    @Override
5415    public final void activityResumed(IBinder token) {
5416        final long origId = Binder.clearCallingIdentity();
5417        synchronized(this) {
5418            ActivityStack stack = ActivityRecord.getStackLocked(token);
5419            if (stack != null) {
5420                ActivityRecord.activityResumedLocked(token);
5421            }
5422        }
5423        Binder.restoreCallingIdentity(origId);
5424    }
5425
5426    @Override
5427    public final void activityPaused(IBinder token) {
5428        final long origId = Binder.clearCallingIdentity();
5429        synchronized(this) {
5430            ActivityStack stack = ActivityRecord.getStackLocked(token);
5431            if (stack != null) {
5432                stack.activityPausedLocked(token, false);
5433            }
5434        }
5435        Binder.restoreCallingIdentity(origId);
5436    }
5437
5438    @Override
5439    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5440            CharSequence description) {
5441        if (localLOGV) Slog.v(
5442            TAG, "Activity stopped: token=" + token);
5443
5444        // Refuse possible leaked file descriptors
5445        if (icicle != null && icicle.hasFileDescriptors()) {
5446            throw new IllegalArgumentException("File descriptors passed in Bundle");
5447        }
5448
5449        final long origId = Binder.clearCallingIdentity();
5450
5451        synchronized (this) {
5452            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5453            if (r != null) {
5454                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5455            }
5456        }
5457
5458        trimApplications();
5459
5460        Binder.restoreCallingIdentity(origId);
5461    }
5462
5463    @Override
5464    public final void activityDestroyed(IBinder token) {
5465        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5466        synchronized (this) {
5467            ActivityStack stack = ActivityRecord.getStackLocked(token);
5468            if (stack != null) {
5469                stack.activityDestroyedLocked(token);
5470            }
5471        }
5472    }
5473
5474    @Override
5475    public String getCallingPackage(IBinder token) {
5476        synchronized (this) {
5477            ActivityRecord r = getCallingRecordLocked(token);
5478            return r != null ? r.info.packageName : null;
5479        }
5480    }
5481
5482    @Override
5483    public ComponentName getCallingActivity(IBinder token) {
5484        synchronized (this) {
5485            ActivityRecord r = getCallingRecordLocked(token);
5486            return r != null ? r.intent.getComponent() : null;
5487        }
5488    }
5489
5490    private ActivityRecord getCallingRecordLocked(IBinder token) {
5491        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5492        if (r == null) {
5493            return null;
5494        }
5495        return r.resultTo;
5496    }
5497
5498    @Override
5499    public ComponentName getActivityClassForToken(IBinder token) {
5500        synchronized(this) {
5501            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5502            if (r == null) {
5503                return null;
5504            }
5505            return r.intent.getComponent();
5506        }
5507    }
5508
5509    @Override
5510    public String getPackageForToken(IBinder token) {
5511        synchronized(this) {
5512            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5513            if (r == null) {
5514                return null;
5515            }
5516            return r.packageName;
5517        }
5518    }
5519
5520    @Override
5521    public IIntentSender getIntentSender(int type,
5522            String packageName, IBinder token, String resultWho,
5523            int requestCode, Intent[] intents, String[] resolvedTypes,
5524            int flags, Bundle options, int userId) {
5525        enforceNotIsolatedCaller("getIntentSender");
5526        // Refuse possible leaked file descriptors
5527        if (intents != null) {
5528            if (intents.length < 1) {
5529                throw new IllegalArgumentException("Intents array length must be >= 1");
5530            }
5531            for (int i=0; i<intents.length; i++) {
5532                Intent intent = intents[i];
5533                if (intent != null) {
5534                    if (intent.hasFileDescriptors()) {
5535                        throw new IllegalArgumentException("File descriptors passed in Intent");
5536                    }
5537                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5538                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5539                        throw new IllegalArgumentException(
5540                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5541                    }
5542                    intents[i] = new Intent(intent);
5543                }
5544            }
5545            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5546                throw new IllegalArgumentException(
5547                        "Intent array length does not match resolvedTypes length");
5548            }
5549        }
5550        if (options != null) {
5551            if (options.hasFileDescriptors()) {
5552                throw new IllegalArgumentException("File descriptors passed in options");
5553            }
5554        }
5555
5556        synchronized(this) {
5557            int callingUid = Binder.getCallingUid();
5558            int origUserId = userId;
5559            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5560                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5561                    "getIntentSender", null);
5562            if (origUserId == UserHandle.USER_CURRENT) {
5563                // We don't want to evaluate this until the pending intent is
5564                // actually executed.  However, we do want to always do the
5565                // security checking for it above.
5566                userId = UserHandle.USER_CURRENT;
5567            }
5568            try {
5569                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5570                    int uid = AppGlobals.getPackageManager()
5571                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5572                    if (!UserHandle.isSameApp(callingUid, uid)) {
5573                        String msg = "Permission Denial: getIntentSender() from pid="
5574                            + Binder.getCallingPid()
5575                            + ", uid=" + Binder.getCallingUid()
5576                            + ", (need uid=" + uid + ")"
5577                            + " is not allowed to send as package " + packageName;
5578                        Slog.w(TAG, msg);
5579                        throw new SecurityException(msg);
5580                    }
5581                }
5582
5583                return getIntentSenderLocked(type, packageName, callingUid, userId,
5584                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5585
5586            } catch (RemoteException e) {
5587                throw new SecurityException(e);
5588            }
5589        }
5590    }
5591
5592    IIntentSender getIntentSenderLocked(int type, String packageName,
5593            int callingUid, int userId, IBinder token, String resultWho,
5594            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5595            Bundle options) {
5596        if (DEBUG_MU)
5597            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5598        ActivityRecord activity = null;
5599        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5600            activity = ActivityRecord.isInStackLocked(token);
5601            if (activity == null) {
5602                return null;
5603            }
5604            if (activity.finishing) {
5605                return null;
5606            }
5607        }
5608
5609        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5610        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5611        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5612        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5613                |PendingIntent.FLAG_UPDATE_CURRENT);
5614
5615        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5616                type, packageName, activity, resultWho,
5617                requestCode, intents, resolvedTypes, flags, options, userId);
5618        WeakReference<PendingIntentRecord> ref;
5619        ref = mIntentSenderRecords.get(key);
5620        PendingIntentRecord rec = ref != null ? ref.get() : null;
5621        if (rec != null) {
5622            if (!cancelCurrent) {
5623                if (updateCurrent) {
5624                    if (rec.key.requestIntent != null) {
5625                        rec.key.requestIntent.replaceExtras(intents != null ?
5626                                intents[intents.length - 1] : null);
5627                    }
5628                    if (intents != null) {
5629                        intents[intents.length-1] = rec.key.requestIntent;
5630                        rec.key.allIntents = intents;
5631                        rec.key.allResolvedTypes = resolvedTypes;
5632                    } else {
5633                        rec.key.allIntents = null;
5634                        rec.key.allResolvedTypes = null;
5635                    }
5636                }
5637                return rec;
5638            }
5639            rec.canceled = true;
5640            mIntentSenderRecords.remove(key);
5641        }
5642        if (noCreate) {
5643            return rec;
5644        }
5645        rec = new PendingIntentRecord(this, key, callingUid);
5646        mIntentSenderRecords.put(key, rec.ref);
5647        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5648            if (activity.pendingResults == null) {
5649                activity.pendingResults
5650                        = new HashSet<WeakReference<PendingIntentRecord>>();
5651            }
5652            activity.pendingResults.add(rec.ref);
5653        }
5654        return rec;
5655    }
5656
5657    @Override
5658    public void cancelIntentSender(IIntentSender sender) {
5659        if (!(sender instanceof PendingIntentRecord)) {
5660            return;
5661        }
5662        synchronized(this) {
5663            PendingIntentRecord rec = (PendingIntentRecord)sender;
5664            try {
5665                int uid = AppGlobals.getPackageManager()
5666                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5667                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5668                    String msg = "Permission Denial: cancelIntentSender() from pid="
5669                        + Binder.getCallingPid()
5670                        + ", uid=" + Binder.getCallingUid()
5671                        + " is not allowed to cancel packges "
5672                        + rec.key.packageName;
5673                    Slog.w(TAG, msg);
5674                    throw new SecurityException(msg);
5675                }
5676            } catch (RemoteException e) {
5677                throw new SecurityException(e);
5678            }
5679            cancelIntentSenderLocked(rec, true);
5680        }
5681    }
5682
5683    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5684        rec.canceled = true;
5685        mIntentSenderRecords.remove(rec.key);
5686        if (cleanActivity && rec.key.activity != null) {
5687            rec.key.activity.pendingResults.remove(rec.ref);
5688        }
5689    }
5690
5691    @Override
5692    public String getPackageForIntentSender(IIntentSender pendingResult) {
5693        if (!(pendingResult instanceof PendingIntentRecord)) {
5694            return null;
5695        }
5696        try {
5697            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5698            return res.key.packageName;
5699        } catch (ClassCastException e) {
5700        }
5701        return null;
5702    }
5703
5704    @Override
5705    public int getUidForIntentSender(IIntentSender sender) {
5706        if (sender instanceof PendingIntentRecord) {
5707            try {
5708                PendingIntentRecord res = (PendingIntentRecord)sender;
5709                return res.uid;
5710            } catch (ClassCastException e) {
5711            }
5712        }
5713        return -1;
5714    }
5715
5716    @Override
5717    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5718        if (!(pendingResult instanceof PendingIntentRecord)) {
5719            return false;
5720        }
5721        try {
5722            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5723            if (res.key.allIntents == null) {
5724                return false;
5725            }
5726            for (int i=0; i<res.key.allIntents.length; i++) {
5727                Intent intent = res.key.allIntents[i];
5728                if (intent.getPackage() != null && intent.getComponent() != null) {
5729                    return false;
5730                }
5731            }
5732            return true;
5733        } catch (ClassCastException e) {
5734        }
5735        return false;
5736    }
5737
5738    @Override
5739    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5740        if (!(pendingResult instanceof PendingIntentRecord)) {
5741            return false;
5742        }
5743        try {
5744            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5745            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5746                return true;
5747            }
5748            return false;
5749        } catch (ClassCastException e) {
5750        }
5751        return false;
5752    }
5753
5754    @Override
5755    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5756        if (!(pendingResult instanceof PendingIntentRecord)) {
5757            return null;
5758        }
5759        try {
5760            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5761            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5762        } catch (ClassCastException e) {
5763        }
5764        return null;
5765    }
5766
5767    @Override
5768    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5769        if (!(pendingResult instanceof PendingIntentRecord)) {
5770            return null;
5771        }
5772        try {
5773            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5774            Intent intent = res.key.requestIntent;
5775            if (intent != null) {
5776                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5777                        || res.lastTagPrefix.equals(prefix))) {
5778                    return res.lastTag;
5779                }
5780                res.lastTagPrefix = prefix;
5781                StringBuilder sb = new StringBuilder(128);
5782                if (prefix != null) {
5783                    sb.append(prefix);
5784                }
5785                if (intent.getAction() != null) {
5786                    sb.append(intent.getAction());
5787                } else if (intent.getComponent() != null) {
5788                    intent.getComponent().appendShortString(sb);
5789                } else {
5790                    sb.append("?");
5791                }
5792                return res.lastTag = sb.toString();
5793            }
5794        } catch (ClassCastException e) {
5795        }
5796        return null;
5797    }
5798
5799    @Override
5800    public void setProcessLimit(int max) {
5801        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5802                "setProcessLimit()");
5803        synchronized (this) {
5804            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5805            mProcessLimitOverride = max;
5806        }
5807        trimApplications();
5808    }
5809
5810    @Override
5811    public int getProcessLimit() {
5812        synchronized (this) {
5813            return mProcessLimitOverride;
5814        }
5815    }
5816
5817    void foregroundTokenDied(ForegroundToken token) {
5818        synchronized (ActivityManagerService.this) {
5819            synchronized (mPidsSelfLocked) {
5820                ForegroundToken cur
5821                    = mForegroundProcesses.get(token.pid);
5822                if (cur != token) {
5823                    return;
5824                }
5825                mForegroundProcesses.remove(token.pid);
5826                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5827                if (pr == null) {
5828                    return;
5829                }
5830                pr.forcingToForeground = null;
5831                updateProcessForegroundLocked(pr, false, false);
5832            }
5833            updateOomAdjLocked();
5834        }
5835    }
5836
5837    @Override
5838    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5839        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5840                "setProcessForeground()");
5841        synchronized(this) {
5842            boolean changed = false;
5843
5844            synchronized (mPidsSelfLocked) {
5845                ProcessRecord pr = mPidsSelfLocked.get(pid);
5846                if (pr == null && isForeground) {
5847                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5848                    return;
5849                }
5850                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5851                if (oldToken != null) {
5852                    oldToken.token.unlinkToDeath(oldToken, 0);
5853                    mForegroundProcesses.remove(pid);
5854                    if (pr != null) {
5855                        pr.forcingToForeground = null;
5856                    }
5857                    changed = true;
5858                }
5859                if (isForeground && token != null) {
5860                    ForegroundToken newToken = new ForegroundToken() {
5861                        @Override
5862                        public void binderDied() {
5863                            foregroundTokenDied(this);
5864                        }
5865                    };
5866                    newToken.pid = pid;
5867                    newToken.token = token;
5868                    try {
5869                        token.linkToDeath(newToken, 0);
5870                        mForegroundProcesses.put(pid, newToken);
5871                        pr.forcingToForeground = token;
5872                        changed = true;
5873                    } catch (RemoteException e) {
5874                        // If the process died while doing this, we will later
5875                        // do the cleanup with the process death link.
5876                    }
5877                }
5878            }
5879
5880            if (changed) {
5881                updateOomAdjLocked();
5882            }
5883        }
5884    }
5885
5886    // =========================================================
5887    // PERMISSIONS
5888    // =========================================================
5889
5890    static class PermissionController extends IPermissionController.Stub {
5891        ActivityManagerService mActivityManagerService;
5892        PermissionController(ActivityManagerService activityManagerService) {
5893            mActivityManagerService = activityManagerService;
5894        }
5895
5896        @Override
5897        public boolean checkPermission(String permission, int pid, int uid) {
5898            return mActivityManagerService.checkPermission(permission, pid,
5899                    uid) == PackageManager.PERMISSION_GRANTED;
5900        }
5901    }
5902
5903    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5904        @Override
5905        public int checkComponentPermission(String permission, int pid, int uid,
5906                int owningUid, boolean exported) {
5907            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5908                    owningUid, exported);
5909        }
5910
5911        @Override
5912        public Object getAMSLock() {
5913            return ActivityManagerService.this;
5914        }
5915    }
5916
5917    /**
5918     * This can be called with or without the global lock held.
5919     */
5920    int checkComponentPermission(String permission, int pid, int uid,
5921            int owningUid, boolean exported) {
5922        // We might be performing an operation on behalf of an indirect binder
5923        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5924        // client identity accordingly before proceeding.
5925        Identity tlsIdentity = sCallerIdentity.get();
5926        if (tlsIdentity != null) {
5927            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5928                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5929            uid = tlsIdentity.uid;
5930            pid = tlsIdentity.pid;
5931        }
5932
5933        if (pid == MY_PID) {
5934            return PackageManager.PERMISSION_GRANTED;
5935        }
5936
5937        return ActivityManager.checkComponentPermission(permission, uid,
5938                owningUid, exported);
5939    }
5940
5941    /**
5942     * As the only public entry point for permissions checking, this method
5943     * can enforce the semantic that requesting a check on a null global
5944     * permission is automatically denied.  (Internally a null permission
5945     * string is used when calling {@link #checkComponentPermission} in cases
5946     * when only uid-based security is needed.)
5947     *
5948     * This can be called with or without the global lock held.
5949     */
5950    @Override
5951    public int checkPermission(String permission, int pid, int uid) {
5952        if (permission == null) {
5953            return PackageManager.PERMISSION_DENIED;
5954        }
5955        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5956    }
5957
5958    /**
5959     * Binder IPC calls go through the public entry point.
5960     * This can be called with or without the global lock held.
5961     */
5962    int checkCallingPermission(String permission) {
5963        return checkPermission(permission,
5964                Binder.getCallingPid(),
5965                UserHandle.getAppId(Binder.getCallingUid()));
5966    }
5967
5968    /**
5969     * This can be called with or without the global lock held.
5970     */
5971    void enforceCallingPermission(String permission, String func) {
5972        if (checkCallingPermission(permission)
5973                == PackageManager.PERMISSION_GRANTED) {
5974            return;
5975        }
5976
5977        String msg = "Permission Denial: " + func + " from pid="
5978                + Binder.getCallingPid()
5979                + ", uid=" + Binder.getCallingUid()
5980                + " requires " + permission;
5981        Slog.w(TAG, msg);
5982        throw new SecurityException(msg);
5983    }
5984
5985    /**
5986     * Determine if UID is holding permissions required to access {@link Uri} in
5987     * the given {@link ProviderInfo}. Final permission checking is always done
5988     * in {@link ContentProvider}.
5989     */
5990    private final boolean checkHoldingPermissionsLocked(
5991            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5992        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5993                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5994
5995        if (pi.applicationInfo.uid == uid) {
5996            return true;
5997        } else if (!pi.exported) {
5998            return false;
5999        }
6000
6001        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6002        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6003        try {
6004            // check if target holds top-level <provider> permissions
6005            if (!readMet && pi.readPermission != null
6006                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6007                readMet = true;
6008            }
6009            if (!writeMet && pi.writePermission != null
6010                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6011                writeMet = true;
6012            }
6013
6014            // track if unprotected read/write is allowed; any denied
6015            // <path-permission> below removes this ability
6016            boolean allowDefaultRead = pi.readPermission == null;
6017            boolean allowDefaultWrite = pi.writePermission == null;
6018
6019            // check if target holds any <path-permission> that match uri
6020            final PathPermission[] pps = pi.pathPermissions;
6021            if (pps != null) {
6022                final String path = uri.getPath();
6023                int i = pps.length;
6024                while (i > 0 && (!readMet || !writeMet)) {
6025                    i--;
6026                    PathPermission pp = pps[i];
6027                    if (pp.match(path)) {
6028                        if (!readMet) {
6029                            final String pprperm = pp.getReadPermission();
6030                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6031                                    + pprperm + " for " + pp.getPath()
6032                                    + ": match=" + pp.match(path)
6033                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6034                            if (pprperm != null) {
6035                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6036                                    readMet = true;
6037                                } else {
6038                                    allowDefaultRead = false;
6039                                }
6040                            }
6041                        }
6042                        if (!writeMet) {
6043                            final String ppwperm = pp.getWritePermission();
6044                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6045                                    + ppwperm + " for " + pp.getPath()
6046                                    + ": match=" + pp.match(path)
6047                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6048                            if (ppwperm != null) {
6049                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6050                                    writeMet = true;
6051                                } else {
6052                                    allowDefaultWrite = false;
6053                                }
6054                            }
6055                        }
6056                    }
6057                }
6058            }
6059
6060            // grant unprotected <provider> read/write, if not blocked by
6061            // <path-permission> above
6062            if (allowDefaultRead) readMet = true;
6063            if (allowDefaultWrite) writeMet = true;
6064
6065        } catch (RemoteException e) {
6066            return false;
6067        }
6068
6069        return readMet && writeMet;
6070    }
6071
6072    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6073        ProviderInfo pi = null;
6074        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6075        if (cpr != null) {
6076            pi = cpr.info;
6077        } else {
6078            try {
6079                pi = AppGlobals.getPackageManager().resolveContentProvider(
6080                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6081            } catch (RemoteException ex) {
6082            }
6083        }
6084        return pi;
6085    }
6086
6087    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6088        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6089        if (targetUris != null) {
6090            return targetUris.get(uri);
6091        }
6092        return null;
6093    }
6094
6095    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6096            String targetPkg, int targetUid, GrantUri uri) {
6097        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6098        if (targetUris == null) {
6099            targetUris = Maps.newArrayMap();
6100            mGrantedUriPermissions.put(targetUid, targetUris);
6101        }
6102
6103        UriPermission perm = targetUris.get(uri);
6104        if (perm == null) {
6105            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6106            targetUris.put(uri, perm);
6107        }
6108
6109        return perm;
6110    }
6111
6112    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6113        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6114        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6115                : UriPermission.STRENGTH_OWNED;
6116
6117        // Root gets to do everything.
6118        if (uid == 0) {
6119            return true;
6120        }
6121
6122        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6123        if (perms == null) return false;
6124
6125        // First look for exact match
6126        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6127        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6128            return true;
6129        }
6130
6131        // No exact match, look for prefixes
6132        final int N = perms.size();
6133        for (int i = 0; i < N; i++) {
6134            final UriPermission perm = perms.valueAt(i);
6135            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6136                    && perm.getStrength(modeFlags) >= minStrength) {
6137                return true;
6138            }
6139        }
6140
6141        return false;
6142    }
6143
6144    @Override
6145    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6146        enforceNotIsolatedCaller("checkUriPermission");
6147
6148        // Another redirected-binder-call permissions check as in
6149        // {@link checkComponentPermission}.
6150        Identity tlsIdentity = sCallerIdentity.get();
6151        if (tlsIdentity != null) {
6152            uid = tlsIdentity.uid;
6153            pid = tlsIdentity.pid;
6154        }
6155
6156        // Our own process gets to do everything.
6157        if (pid == MY_PID) {
6158            return PackageManager.PERMISSION_GRANTED;
6159        }
6160        synchronized (this) {
6161            return checkUriPermissionLocked(uri, uid, modeFlags)
6162                    ? PackageManager.PERMISSION_GRANTED
6163                    : PackageManager.PERMISSION_DENIED;
6164        }
6165    }
6166
6167    /**
6168     * Check if the targetPkg can be granted permission to access uri by
6169     * the callingUid using the given modeFlags.  Throws a security exception
6170     * if callingUid is not allowed to do this.  Returns the uid of the target
6171     * if the URI permission grant should be performed; returns -1 if it is not
6172     * needed (for example targetPkg already has permission to access the URI).
6173     * If you already know the uid of the target, you can supply it in
6174     * lastTargetUid else set that to -1.
6175     */
6176    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6177            Uri uri, final int modeFlags, int lastTargetUid) {
6178        if (!Intent.isAccessUriMode(modeFlags)) {
6179            return -1;
6180        }
6181
6182        if (targetPkg != null) {
6183            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6184                    "Checking grant " + targetPkg + " permission to " + uri);
6185        }
6186
6187        final IPackageManager pm = AppGlobals.getPackageManager();
6188
6189        // If this is not a content: uri, we can't do anything with it.
6190        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6191            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6192                    "Can't grant URI permission for non-content URI: " + uri);
6193            return -1;
6194        }
6195
6196        final String authority = uri.getAuthority();
6197        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6198        if (pi == null) {
6199            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6200            return -1;
6201        }
6202
6203        int targetUid = lastTargetUid;
6204        if (targetUid < 0 && targetPkg != null) {
6205            try {
6206                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6207                if (targetUid < 0) {
6208                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6209                            "Can't grant URI permission no uid for: " + targetPkg);
6210                    return -1;
6211                }
6212            } catch (RemoteException ex) {
6213                return -1;
6214            }
6215        }
6216
6217        if (targetUid >= 0) {
6218            // First...  does the target actually need this permission?
6219            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6220                // No need to grant the target this permission.
6221                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6222                        "Target " + targetPkg + " already has full permission to " + uri);
6223                return -1;
6224            }
6225        } else {
6226            // First...  there is no target package, so can anyone access it?
6227            boolean allowed = pi.exported;
6228            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6229                if (pi.readPermission != null) {
6230                    allowed = false;
6231                }
6232            }
6233            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6234                if (pi.writePermission != null) {
6235                    allowed = false;
6236                }
6237            }
6238            if (allowed) {
6239                return -1;
6240            }
6241        }
6242
6243        // Second...  is the provider allowing granting of URI permissions?
6244        if (!pi.grantUriPermissions) {
6245            throw new SecurityException("Provider " + pi.packageName
6246                    + "/" + pi.name
6247                    + " does not allow granting of Uri permissions (uri "
6248                    + uri + ")");
6249        }
6250        if (pi.uriPermissionPatterns != null) {
6251            final int N = pi.uriPermissionPatterns.length;
6252            boolean allowed = false;
6253            for (int i=0; i<N; i++) {
6254                if (pi.uriPermissionPatterns[i] != null
6255                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6256                    allowed = true;
6257                    break;
6258                }
6259            }
6260            if (!allowed) {
6261                throw new SecurityException("Provider " + pi.packageName
6262                        + "/" + pi.name
6263                        + " does not allow granting of permission to path of Uri "
6264                        + uri);
6265            }
6266        }
6267
6268        // Third...  does the caller itself have permission to access
6269        // this uri?
6270        if (callingUid != Process.myUid()) {
6271            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6272                // Require they hold a strong enough Uri permission
6273                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6274                    throw new SecurityException("Uid " + callingUid
6275                            + " does not have permission to uri " + uri);
6276                }
6277            }
6278        }
6279
6280        return targetUid;
6281    }
6282
6283    @Override
6284    public int checkGrantUriPermission(int callingUid, String targetPkg,
6285            Uri uri, final int modeFlags) {
6286        enforceNotIsolatedCaller("checkGrantUriPermission");
6287        synchronized(this) {
6288            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6289        }
6290    }
6291
6292    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6293            final int modeFlags, UriPermissionOwner owner) {
6294        if (!Intent.isAccessUriMode(modeFlags)) {
6295            return;
6296        }
6297
6298        // So here we are: the caller has the assumed permission
6299        // to the uri, and the target doesn't.  Let's now give this to
6300        // the target.
6301
6302        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6303                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6304
6305        final String authority = uri.getAuthority();
6306        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6307        if (pi == null) {
6308            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6309            return;
6310        }
6311
6312        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6313        final UriPermission perm = findOrCreateUriPermissionLocked(
6314                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6315        perm.grantModes(modeFlags, owner);
6316    }
6317
6318    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6319            final int modeFlags, UriPermissionOwner owner) {
6320        if (targetPkg == null) {
6321            throw new NullPointerException("targetPkg");
6322        }
6323
6324        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6325        if (targetUid < 0) {
6326            return;
6327        }
6328
6329        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6330    }
6331
6332    static class NeededUriGrants extends ArrayList<Uri> {
6333        final String targetPkg;
6334        final int targetUid;
6335        final int flags;
6336
6337        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6338            this.targetPkg = targetPkg;
6339            this.targetUid = targetUid;
6340            this.flags = flags;
6341        }
6342    }
6343
6344    /**
6345     * Like checkGrantUriPermissionLocked, but takes an Intent.
6346     */
6347    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6348            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6349        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6350                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6351                + " clip=" + (intent != null ? intent.getClipData() : null)
6352                + " from " + intent + "; flags=0x"
6353                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6354
6355        if (targetPkg == null) {
6356            throw new NullPointerException("targetPkg");
6357        }
6358
6359        if (intent == null) {
6360            return null;
6361        }
6362        Uri data = intent.getData();
6363        ClipData clip = intent.getClipData();
6364        if (data == null && clip == null) {
6365            return null;
6366        }
6367
6368        if (data != null) {
6369            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6370                mode, needed != null ? needed.targetUid : -1);
6371            if (targetUid > 0) {
6372                if (needed == null) {
6373                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6374                }
6375                needed.add(data);
6376            }
6377        }
6378        if (clip != null) {
6379            for (int i=0; i<clip.getItemCount(); i++) {
6380                Uri uri = clip.getItemAt(i).getUri();
6381                if (uri != null) {
6382                    int targetUid = -1;
6383                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6384                            mode, needed != null ? needed.targetUid : -1);
6385                    if (targetUid > 0) {
6386                        if (needed == null) {
6387                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6388                        }
6389                        needed.add(uri);
6390                    }
6391                } else {
6392                    Intent clipIntent = clip.getItemAt(i).getIntent();
6393                    if (clipIntent != null) {
6394                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6395                                callingUid, targetPkg, clipIntent, mode, needed);
6396                        if (newNeeded != null) {
6397                            needed = newNeeded;
6398                        }
6399                    }
6400                }
6401            }
6402        }
6403
6404        return needed;
6405    }
6406
6407    /**
6408     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6409     */
6410    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6411            UriPermissionOwner owner) {
6412        if (needed != null) {
6413            for (int i=0; i<needed.size(); i++) {
6414                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6415                        needed.get(i), needed.flags, owner);
6416            }
6417        }
6418    }
6419
6420    void grantUriPermissionFromIntentLocked(int callingUid,
6421            String targetPkg, Intent intent, UriPermissionOwner owner) {
6422        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6423                intent, intent != null ? intent.getFlags() : 0, null);
6424        if (needed == null) {
6425            return;
6426        }
6427
6428        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6429    }
6430
6431    @Override
6432    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6433            Uri uri, final int modeFlags) {
6434        enforceNotIsolatedCaller("grantUriPermission");
6435        synchronized(this) {
6436            final ProcessRecord r = getRecordForAppLocked(caller);
6437            if (r == null) {
6438                throw new SecurityException("Unable to find app for caller "
6439                        + caller
6440                        + " when granting permission to uri " + uri);
6441            }
6442            if (targetPkg == null) {
6443                throw new IllegalArgumentException("null target");
6444            }
6445            if (uri == null) {
6446                throw new IllegalArgumentException("null uri");
6447            }
6448
6449            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6450                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6451                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6452                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6453
6454            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6455        }
6456    }
6457
6458    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6459        if (perm.modeFlags == 0) {
6460            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6461                    perm.targetUid);
6462            if (perms != null) {
6463                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6464                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6465
6466                perms.remove(perm.uri);
6467                if (perms.isEmpty()) {
6468                    mGrantedUriPermissions.remove(perm.targetUid);
6469                }
6470            }
6471        }
6472    }
6473
6474    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6475        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6476
6477        final IPackageManager pm = AppGlobals.getPackageManager();
6478        final String authority = uri.getAuthority();
6479        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6480        if (pi == null) {
6481            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6482            return;
6483        }
6484
6485        // Does the caller have this permission on the URI?
6486        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6487            // Right now, if you are not the original owner of the permission,
6488            // you are not allowed to revoke it.
6489            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6490                throw new SecurityException("Uid " + callingUid
6491                        + " does not have permission to uri " + uri);
6492            //}
6493        }
6494
6495        boolean persistChanged = false;
6496
6497        // Go through all of the permissions and remove any that match.
6498        int N = mGrantedUriPermissions.size();
6499        for (int i = 0; i < N; i++) {
6500            final int targetUid = mGrantedUriPermissions.keyAt(i);
6501            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6502
6503            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6504                final UriPermission perm = it.next();
6505                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6506                    if (DEBUG_URI_PERMISSION)
6507                        Slog.v(TAG,
6508                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6509                    persistChanged |= perm.revokeModes(
6510                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6511                    if (perm.modeFlags == 0) {
6512                        it.remove();
6513                    }
6514                }
6515            }
6516
6517            if (perms.isEmpty()) {
6518                mGrantedUriPermissions.remove(targetUid);
6519                N--;
6520                i--;
6521            }
6522        }
6523
6524        if (persistChanged) {
6525            schedulePersistUriGrants();
6526        }
6527    }
6528
6529    @Override
6530    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6531            final int modeFlags) {
6532        enforceNotIsolatedCaller("revokeUriPermission");
6533        synchronized(this) {
6534            final ProcessRecord r = getRecordForAppLocked(caller);
6535            if (r == null) {
6536                throw new SecurityException("Unable to find app for caller "
6537                        + caller
6538                        + " when revoking permission to uri " + uri);
6539            }
6540            if (uri == null) {
6541                Slog.w(TAG, "revokeUriPermission: null uri");
6542                return;
6543            }
6544
6545            if (!Intent.isAccessUriMode(modeFlags)) {
6546                return;
6547            }
6548
6549            final IPackageManager pm = AppGlobals.getPackageManager();
6550            final String authority = uri.getAuthority();
6551            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6552            if (pi == null) {
6553                Slog.w(TAG, "No content provider found for permission revoke: "
6554                        + uri.toSafeString());
6555                return;
6556            }
6557
6558            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6559        }
6560    }
6561
6562    /**
6563     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6564     * given package.
6565     *
6566     * @param packageName Package name to match, or {@code null} to apply to all
6567     *            packages.
6568     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6569     *            to all users.
6570     * @param persistable If persistable grants should be removed.
6571     */
6572    private void removeUriPermissionsForPackageLocked(
6573            String packageName, int userHandle, boolean persistable) {
6574        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6575            throw new IllegalArgumentException("Must narrow by either package or user");
6576        }
6577
6578        boolean persistChanged = false;
6579
6580        int N = mGrantedUriPermissions.size();
6581        for (int i = 0; i < N; i++) {
6582            final int targetUid = mGrantedUriPermissions.keyAt(i);
6583            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6584
6585            // Only inspect grants matching user
6586            if (userHandle == UserHandle.USER_ALL
6587                    || userHandle == UserHandle.getUserId(targetUid)) {
6588                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6589                    final UriPermission perm = it.next();
6590
6591                    // Only inspect grants matching package
6592                    if (packageName == null || perm.sourcePkg.equals(packageName)
6593                            || perm.targetPkg.equals(packageName)) {
6594                        persistChanged |= perm.revokeModes(
6595                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6596
6597                        // Only remove when no modes remain; any persisted grants
6598                        // will keep this alive.
6599                        if (perm.modeFlags == 0) {
6600                            it.remove();
6601                        }
6602                    }
6603                }
6604
6605                if (perms.isEmpty()) {
6606                    mGrantedUriPermissions.remove(targetUid);
6607                    N--;
6608                    i--;
6609                }
6610            }
6611        }
6612
6613        if (persistChanged) {
6614            schedulePersistUriGrants();
6615        }
6616    }
6617
6618    @Override
6619    public IBinder newUriPermissionOwner(String name) {
6620        enforceNotIsolatedCaller("newUriPermissionOwner");
6621        synchronized(this) {
6622            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6623            return owner.getExternalTokenLocked();
6624        }
6625    }
6626
6627    @Override
6628    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6629            Uri uri, final int modeFlags) {
6630        synchronized(this) {
6631            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6632            if (owner == null) {
6633                throw new IllegalArgumentException("Unknown owner: " + token);
6634            }
6635            if (fromUid != Binder.getCallingUid()) {
6636                if (Binder.getCallingUid() != Process.myUid()) {
6637                    // Only system code can grant URI permissions on behalf
6638                    // of other users.
6639                    throw new SecurityException("nice try");
6640                }
6641            }
6642            if (targetPkg == null) {
6643                throw new IllegalArgumentException("null target");
6644            }
6645            if (uri == null) {
6646                throw new IllegalArgumentException("null uri");
6647            }
6648
6649            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6650        }
6651    }
6652
6653    @Override
6654    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6655        synchronized(this) {
6656            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6657            if (owner == null) {
6658                throw new IllegalArgumentException("Unknown owner: " + token);
6659            }
6660
6661            if (uri == null) {
6662                owner.removeUriPermissionsLocked(mode);
6663            } else {
6664                owner.removeUriPermissionLocked(uri, mode);
6665            }
6666        }
6667    }
6668
6669    private void schedulePersistUriGrants() {
6670        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6671            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6672                    10 * DateUtils.SECOND_IN_MILLIS);
6673        }
6674    }
6675
6676    private void writeGrantedUriPermissions() {
6677        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6678
6679        // Snapshot permissions so we can persist without lock
6680        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6681        synchronized (this) {
6682            final int size = mGrantedUriPermissions.size();
6683            for (int i = 0; i < size; i++) {
6684                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6685                for (UriPermission perm : perms.values()) {
6686                    if (perm.persistedModeFlags != 0) {
6687                        persist.add(perm.snapshot());
6688                    }
6689                }
6690            }
6691        }
6692
6693        FileOutputStream fos = null;
6694        try {
6695            fos = mGrantFile.startWrite();
6696
6697            XmlSerializer out = new FastXmlSerializer();
6698            out.setOutput(fos, "utf-8");
6699            out.startDocument(null, true);
6700            out.startTag(null, TAG_URI_GRANTS);
6701            for (UriPermission.Snapshot perm : persist) {
6702                out.startTag(null, TAG_URI_GRANT);
6703                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6704                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6705                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6706                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6707                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6708                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6709                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6710                out.endTag(null, TAG_URI_GRANT);
6711            }
6712            out.endTag(null, TAG_URI_GRANTS);
6713            out.endDocument();
6714
6715            mGrantFile.finishWrite(fos);
6716        } catch (IOException e) {
6717            if (fos != null) {
6718                mGrantFile.failWrite(fos);
6719            }
6720        }
6721    }
6722
6723    private void readGrantedUriPermissionsLocked() {
6724        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6725
6726        final long now = System.currentTimeMillis();
6727
6728        FileInputStream fis = null;
6729        try {
6730            fis = mGrantFile.openRead();
6731            final XmlPullParser in = Xml.newPullParser();
6732            in.setInput(fis, null);
6733
6734            int type;
6735            while ((type = in.next()) != END_DOCUMENT) {
6736                final String tag = in.getName();
6737                if (type == START_TAG) {
6738                    if (TAG_URI_GRANT.equals(tag)) {
6739                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6740                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6741                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6742                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6743                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6744                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6745                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6746
6747                        // Sanity check that provider still belongs to source package
6748                        final ProviderInfo pi = getProviderInfoLocked(
6749                                uri.getAuthority(), userHandle);
6750                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6751                            int targetUid = -1;
6752                            try {
6753                                targetUid = AppGlobals.getPackageManager()
6754                                        .getPackageUid(targetPkg, userHandle);
6755                            } catch (RemoteException e) {
6756                            }
6757                            if (targetUid != -1) {
6758                                final UriPermission perm = findOrCreateUriPermissionLocked(
6759                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6760                                perm.initPersistedModes(modeFlags, createdTime);
6761                            }
6762                        } else {
6763                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6764                                    + " but instead found " + pi);
6765                        }
6766                    }
6767                }
6768            }
6769        } catch (FileNotFoundException e) {
6770            // Missing grants is okay
6771        } catch (IOException e) {
6772            Log.wtf(TAG, "Failed reading Uri grants", e);
6773        } catch (XmlPullParserException e) {
6774            Log.wtf(TAG, "Failed reading Uri grants", e);
6775        } finally {
6776            IoUtils.closeQuietly(fis);
6777        }
6778    }
6779
6780    @Override
6781    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6782        enforceNotIsolatedCaller("takePersistableUriPermission");
6783
6784        Preconditions.checkFlagsArgument(modeFlags,
6785                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6786
6787        synchronized (this) {
6788            final int callingUid = Binder.getCallingUid();
6789            boolean persistChanged = false;
6790
6791            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6792            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6793
6794            final boolean exactValid = (exactPerm != null)
6795                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6796            final boolean prefixValid = (prefixPerm != null)
6797                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6798
6799            if (!(exactValid || prefixValid)) {
6800                throw new SecurityException("No persistable permission grants found for UID "
6801                        + callingUid + " and Uri " + uri.toSafeString());
6802            }
6803
6804            if (exactValid) {
6805                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6806            }
6807            if (prefixValid) {
6808                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6809            }
6810
6811            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6812
6813            if (persistChanged) {
6814                schedulePersistUriGrants();
6815            }
6816        }
6817    }
6818
6819    @Override
6820    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6821        enforceNotIsolatedCaller("releasePersistableUriPermission");
6822
6823        Preconditions.checkFlagsArgument(modeFlags,
6824                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6825
6826        synchronized (this) {
6827            final int callingUid = Binder.getCallingUid();
6828            boolean persistChanged = false;
6829
6830            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6831            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6832            if (exactPerm == null && prefixPerm == null) {
6833                throw new SecurityException("No permission grants found for UID " + callingUid
6834                        + " and Uri " + uri.toSafeString());
6835            }
6836
6837            if (exactPerm != null) {
6838                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6839                removeUriPermissionIfNeededLocked(exactPerm);
6840            }
6841            if (prefixPerm != null) {
6842                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6843                removeUriPermissionIfNeededLocked(prefixPerm);
6844            }
6845
6846            if (persistChanged) {
6847                schedulePersistUriGrants();
6848            }
6849        }
6850    }
6851
6852    /**
6853     * Prune any older {@link UriPermission} for the given UID until outstanding
6854     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6855     *
6856     * @return if any mutations occured that require persisting.
6857     */
6858    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6859        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6860        if (perms == null) return false;
6861        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6862
6863        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6864        for (UriPermission perm : perms.values()) {
6865            if (perm.persistedModeFlags != 0) {
6866                persisted.add(perm);
6867            }
6868        }
6869
6870        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6871        if (trimCount <= 0) return false;
6872
6873        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6874        for (int i = 0; i < trimCount; i++) {
6875            final UriPermission perm = persisted.get(i);
6876
6877            if (DEBUG_URI_PERMISSION) {
6878                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6879            }
6880
6881            perm.releasePersistableModes(~0);
6882            removeUriPermissionIfNeededLocked(perm);
6883        }
6884
6885        return true;
6886    }
6887
6888    @Override
6889    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6890            String packageName, boolean incoming) {
6891        enforceNotIsolatedCaller("getPersistedUriPermissions");
6892        Preconditions.checkNotNull(packageName, "packageName");
6893
6894        final int callingUid = Binder.getCallingUid();
6895        final IPackageManager pm = AppGlobals.getPackageManager();
6896        try {
6897            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6898            if (packageUid != callingUid) {
6899                throw new SecurityException(
6900                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6901            }
6902        } catch (RemoteException e) {
6903            throw new SecurityException("Failed to verify package name ownership");
6904        }
6905
6906        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6907        synchronized (this) {
6908            if (incoming) {
6909                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6910                        callingUid);
6911                if (perms == null) {
6912                    Slog.w(TAG, "No permission grants found for " + packageName);
6913                } else {
6914                    for (UriPermission perm : perms.values()) {
6915                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6916                            result.add(perm.buildPersistedPublicApiObject());
6917                        }
6918                    }
6919                }
6920            } else {
6921                final int size = mGrantedUriPermissions.size();
6922                for (int i = 0; i < size; i++) {
6923                    final ArrayMap<GrantUri, UriPermission> perms =
6924                            mGrantedUriPermissions.valueAt(i);
6925                    for (UriPermission perm : perms.values()) {
6926                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6927                            result.add(perm.buildPersistedPublicApiObject());
6928                        }
6929                    }
6930                }
6931            }
6932        }
6933        return new ParceledListSlice<android.content.UriPermission>(result);
6934    }
6935
6936    @Override
6937    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6938        synchronized (this) {
6939            ProcessRecord app =
6940                who != null ? getRecordForAppLocked(who) : null;
6941            if (app == null) return;
6942
6943            Message msg = Message.obtain();
6944            msg.what = WAIT_FOR_DEBUGGER_MSG;
6945            msg.obj = app;
6946            msg.arg1 = waiting ? 1 : 0;
6947            mHandler.sendMessage(msg);
6948        }
6949    }
6950
6951    @Override
6952    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6953        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6954        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6955        outInfo.availMem = Process.getFreeMemory();
6956        outInfo.totalMem = Process.getTotalMemory();
6957        outInfo.threshold = homeAppMem;
6958        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6959        outInfo.hiddenAppThreshold = cachedAppMem;
6960        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6961                ProcessList.SERVICE_ADJ);
6962        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6963                ProcessList.VISIBLE_APP_ADJ);
6964        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6965                ProcessList.FOREGROUND_APP_ADJ);
6966    }
6967
6968    // =========================================================
6969    // TASK MANAGEMENT
6970    // =========================================================
6971
6972    @Override
6973    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6974        final int callingUid = Binder.getCallingUid();
6975        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6976
6977        synchronized(this) {
6978            if (localLOGV) Slog.v(
6979                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6980
6981            final boolean allowed = checkCallingPermission(
6982                    android.Manifest.permission.GET_TASKS)
6983                    == PackageManager.PERMISSION_GRANTED;
6984            if (!allowed) {
6985                Slog.w(TAG, "getTasks: caller " + callingUid
6986                        + " does not hold GET_TASKS; limiting output");
6987            }
6988
6989            // TODO: Improve with MRU list from all ActivityStacks.
6990            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6991        }
6992
6993        return list;
6994    }
6995
6996    TaskRecord getMostRecentTask() {
6997        return mRecentTasks.get(0);
6998    }
6999
7000    @Override
7001    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7002            int flags, int userId) {
7003        final int callingUid = Binder.getCallingUid();
7004        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7005                false, true, "getRecentTasks", null);
7006
7007        synchronized (this) {
7008            final boolean allowed = checkCallingPermission(
7009                    android.Manifest.permission.GET_TASKS)
7010                    == PackageManager.PERMISSION_GRANTED;
7011            if (!allowed) {
7012                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7013                        + " does not hold GET_TASKS; limiting output");
7014            }
7015            final boolean detailed = checkCallingPermission(
7016                    android.Manifest.permission.GET_DETAILED_TASKS)
7017                    == PackageManager.PERMISSION_GRANTED;
7018
7019            IPackageManager pm = AppGlobals.getPackageManager();
7020
7021            final int N = mRecentTasks.size();
7022            ArrayList<ActivityManager.RecentTaskInfo> res
7023                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7024                            maxNum < N ? maxNum : N);
7025
7026            final Set<Integer> includedUsers;
7027            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7028                includedUsers = getProfileIdsLocked(userId);
7029            } else {
7030                includedUsers = new HashSet<Integer>();
7031            }
7032            includedUsers.add(Integer.valueOf(userId));
7033            for (int i=0; i<N && maxNum > 0; i++) {
7034                TaskRecord tr = mRecentTasks.get(i);
7035                // Only add calling user or related users recent tasks
7036                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7037
7038                // Return the entry if desired by the caller.  We always return
7039                // the first entry, because callers always expect this to be the
7040                // foreground app.  We may filter others if the caller has
7041                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7042                // we should exclude the entry.
7043
7044                if (i == 0
7045                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7046                        || (tr.intent == null)
7047                        || ((tr.intent.getFlags()
7048                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7049                    if (!allowed) {
7050                        // If the caller doesn't have the GET_TASKS permission, then only
7051                        // allow them to see a small subset of tasks -- their own and home.
7052                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7053                            continue;
7054                        }
7055                    }
7056                    ActivityManager.RecentTaskInfo rti
7057                            = new ActivityManager.RecentTaskInfo();
7058                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7059                    rti.persistentId = tr.taskId;
7060                    rti.baseIntent = new Intent(
7061                            tr.intent != null ? tr.intent : tr.affinityIntent);
7062                    if (!detailed) {
7063                        rti.baseIntent.replaceExtras((Bundle)null);
7064                    }
7065                    rti.origActivity = tr.origActivity;
7066                    rti.description = tr.lastDescription;
7067                    rti.stackId = tr.stack.mStackId;
7068                    rti.userId = tr.userId;
7069
7070                    // Traverse upwards looking for any break between main task activities and
7071                    // utility activities.
7072                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7073                    int activityNdx;
7074                    final int numActivities = activities.size();
7075                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7076                            ++activityNdx) {
7077                        final ActivityRecord r = activities.get(activityNdx);
7078                        if (r.intent != null &&
7079                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7080                                        != 0) {
7081                            break;
7082                        }
7083                    }
7084                    if (activityNdx > 0) {
7085                        // Traverse downwards starting below break looking for set label, icon.
7086                        // Note that if there are activities in the task but none of them set the
7087                        // recent activity values, then we do not fall back to the last set
7088                        // values in the TaskRecord.
7089                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7090                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7091                            final ActivityRecord r = activities.get(activityNdx);
7092                            if (r.activityValues != null) {
7093                                if (rti.activityValues.label == null) {
7094                                    rti.activityValues.label = r.activityValues.label;
7095                                    tr.lastActivityValues.label = r.activityValues.label;
7096                                }
7097                                if (rti.activityValues.icon == null) {
7098                                    rti.activityValues.icon = r.activityValues.icon;
7099                                    tr.lastActivityValues.icon = r.activityValues.icon;
7100                                }
7101                                if (rti.activityValues.colorPrimary == 0) {
7102                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7103                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7104                                }
7105                            }
7106                        }
7107                    } else {
7108                        // If there are no activity records in this task, then we use the last
7109                        // resolved values
7110                        rti.activityValues =
7111                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7112                    }
7113
7114                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7115                        // Check whether this activity is currently available.
7116                        try {
7117                            if (rti.origActivity != null) {
7118                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7119                                        == null) {
7120                                    continue;
7121                                }
7122                            } else if (rti.baseIntent != null) {
7123                                if (pm.queryIntentActivities(rti.baseIntent,
7124                                        null, 0, userId) == null) {
7125                                    continue;
7126                                }
7127                            }
7128                        } catch (RemoteException e) {
7129                            // Will never happen.
7130                        }
7131                    }
7132
7133                    res.add(rti);
7134                    maxNum--;
7135                }
7136            }
7137            return res;
7138        }
7139    }
7140
7141    private TaskRecord recentTaskForIdLocked(int id) {
7142        final int N = mRecentTasks.size();
7143            for (int i=0; i<N; i++) {
7144                TaskRecord tr = mRecentTasks.get(i);
7145                if (tr.taskId == id) {
7146                    return tr;
7147                }
7148            }
7149            return null;
7150    }
7151
7152    @Override
7153    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7154        synchronized (this) {
7155            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7156                    "getTaskThumbnails()");
7157            TaskRecord tr = recentTaskForIdLocked(id);
7158            if (tr != null) {
7159                return tr.getTaskThumbnailsLocked();
7160            }
7161        }
7162        return null;
7163    }
7164
7165    @Override
7166    public Bitmap getTaskTopThumbnail(int id) {
7167        synchronized (this) {
7168            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7169                    "getTaskTopThumbnail()");
7170            TaskRecord tr = recentTaskForIdLocked(id);
7171            if (tr != null) {
7172                return tr.getTaskTopThumbnailLocked();
7173            }
7174        }
7175        return null;
7176    }
7177
7178    @Override
7179    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7180        synchronized (this) {
7181            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7182            if (r != null) {
7183                r.activityValues = rav;
7184            }
7185        }
7186    }
7187
7188    @Override
7189    public boolean removeSubTask(int taskId, int subTaskIndex) {
7190        synchronized (this) {
7191            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7192                    "removeSubTask()");
7193            long ident = Binder.clearCallingIdentity();
7194            try {
7195                TaskRecord tr = recentTaskForIdLocked(taskId);
7196                if (tr != null) {
7197                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7198                }
7199                return false;
7200            } finally {
7201                Binder.restoreCallingIdentity(ident);
7202            }
7203        }
7204    }
7205
7206    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7207        if (!pr.killedByAm) {
7208            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7209            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7210                    pr.processName, pr.setAdj, reason);
7211            pr.killedByAm = true;
7212            Process.killProcessQuiet(pr.pid);
7213        }
7214    }
7215
7216    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7217        tr.disposeThumbnail();
7218        mRecentTasks.remove(tr);
7219        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7220        Intent baseIntent = new Intent(
7221                tr.intent != null ? tr.intent : tr.affinityIntent);
7222        ComponentName component = baseIntent.getComponent();
7223        if (component == null) {
7224            Slog.w(TAG, "Now component for base intent of task: " + tr);
7225            return;
7226        }
7227
7228        // Find any running services associated with this app.
7229        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7230
7231        if (killProcesses) {
7232            // Find any running processes associated with this app.
7233            final String pkg = component.getPackageName();
7234            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7235            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7236            for (int i=0; i<pmap.size(); i++) {
7237                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7238                for (int j=0; j<uids.size(); j++) {
7239                    ProcessRecord proc = uids.valueAt(j);
7240                    if (proc.userId != tr.userId) {
7241                        continue;
7242                    }
7243                    if (!proc.pkgList.containsKey(pkg)) {
7244                        continue;
7245                    }
7246                    procs.add(proc);
7247                }
7248            }
7249
7250            // Kill the running processes.
7251            for (int i=0; i<procs.size(); i++) {
7252                ProcessRecord pr = procs.get(i);
7253                if (pr == mHomeProcess) {
7254                    // Don't kill the home process along with tasks from the same package.
7255                    continue;
7256                }
7257                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7258                    killUnneededProcessLocked(pr, "remove task");
7259                } else {
7260                    pr.waitingToKill = "remove task";
7261                }
7262            }
7263        }
7264    }
7265
7266    /**
7267     * Removes the task with the specified task id.
7268     *
7269     * @param taskId Identifier of the task to be removed.
7270     * @param flags Additional operational flags.  May be 0 or
7271     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7272     * @return Returns true if the given task was found and removed.
7273     */
7274    private boolean removeTaskByIdLocked(int taskId, int flags) {
7275        TaskRecord tr = recentTaskForIdLocked(taskId);
7276        if (tr != null) {
7277            tr.removeTaskActivitiesLocked(-1, false);
7278            cleanUpRemovedTaskLocked(tr, flags);
7279            return true;
7280        }
7281        return false;
7282    }
7283
7284    @Override
7285    public boolean removeTask(int taskId, int flags) {
7286        synchronized (this) {
7287            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7288                    "removeTask()");
7289            long ident = Binder.clearCallingIdentity();
7290            try {
7291                return removeTaskByIdLocked(taskId, flags);
7292            } finally {
7293                Binder.restoreCallingIdentity(ident);
7294            }
7295        }
7296    }
7297
7298    /**
7299     * TODO: Add mController hook
7300     */
7301    @Override
7302    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7303        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7304                "moveTaskToFront()");
7305
7306        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7307        synchronized(this) {
7308            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7309                    Binder.getCallingUid(), "Task to front")) {
7310                ActivityOptions.abort(options);
7311                return;
7312            }
7313            final long origId = Binder.clearCallingIdentity();
7314            try {
7315                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7316                if (task == null) {
7317                    return;
7318                }
7319                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7320                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7321                    return;
7322                }
7323                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7324            } finally {
7325                Binder.restoreCallingIdentity(origId);
7326            }
7327            ActivityOptions.abort(options);
7328        }
7329    }
7330
7331    @Override
7332    public void moveTaskToBack(int taskId) {
7333        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7334                "moveTaskToBack()");
7335
7336        synchronized(this) {
7337            TaskRecord tr = recentTaskForIdLocked(taskId);
7338            if (tr != null) {
7339                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7340                ActivityStack stack = tr.stack;
7341                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7342                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7343                            Binder.getCallingUid(), "Task to back")) {
7344                        return;
7345                    }
7346                }
7347                final long origId = Binder.clearCallingIdentity();
7348                try {
7349                    stack.moveTaskToBackLocked(taskId, null);
7350                } finally {
7351                    Binder.restoreCallingIdentity(origId);
7352                }
7353            }
7354        }
7355    }
7356
7357    /**
7358     * Moves an activity, and all of the other activities within the same task, to the bottom
7359     * of the history stack.  The activity's order within the task is unchanged.
7360     *
7361     * @param token A reference to the activity we wish to move
7362     * @param nonRoot If false then this only works if the activity is the root
7363     *                of a task; if true it will work for any activity in a task.
7364     * @return Returns true if the move completed, false if not.
7365     */
7366    @Override
7367    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7368        enforceNotIsolatedCaller("moveActivityTaskToBack");
7369        synchronized(this) {
7370            final long origId = Binder.clearCallingIdentity();
7371            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7372            if (taskId >= 0) {
7373                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7374            }
7375            Binder.restoreCallingIdentity(origId);
7376        }
7377        return false;
7378    }
7379
7380    @Override
7381    public void moveTaskBackwards(int task) {
7382        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7383                "moveTaskBackwards()");
7384
7385        synchronized(this) {
7386            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7387                    Binder.getCallingUid(), "Task backwards")) {
7388                return;
7389            }
7390            final long origId = Binder.clearCallingIdentity();
7391            moveTaskBackwardsLocked(task);
7392            Binder.restoreCallingIdentity(origId);
7393        }
7394    }
7395
7396    private final void moveTaskBackwardsLocked(int task) {
7397        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7398    }
7399
7400    @Override
7401    public IBinder getHomeActivityToken() throws RemoteException {
7402        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7403                "getHomeActivityToken()");
7404        synchronized (this) {
7405            return mStackSupervisor.getHomeActivityToken();
7406        }
7407    }
7408
7409    @Override
7410    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7411            IActivityContainerCallback callback) throws RemoteException {
7412        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7413                "createActivityContainer()");
7414        synchronized (this) {
7415            if (parentActivityToken == null) {
7416                throw new IllegalArgumentException("parent token must not be null");
7417            }
7418            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7419            if (r == null) {
7420                return null;
7421            }
7422            if (callback == null) {
7423                throw new IllegalArgumentException("callback must not be null");
7424            }
7425            return mStackSupervisor.createActivityContainer(r, callback);
7426        }
7427    }
7428
7429    @Override
7430    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7431        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7432                "deleteActivityContainer()");
7433        synchronized (this) {
7434            mStackSupervisor.deleteActivityContainer(container);
7435        }
7436    }
7437
7438    @Override
7439    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7440            throws RemoteException {
7441        synchronized (this) {
7442            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7443            if (stack != null) {
7444                return stack.mActivityContainer;
7445            }
7446            return null;
7447        }
7448    }
7449
7450    @Override
7451    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7452        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7453                "moveTaskToStack()");
7454        if (stackId == HOME_STACK_ID) {
7455            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7456                    new RuntimeException("here").fillInStackTrace());
7457        }
7458        synchronized (this) {
7459            long ident = Binder.clearCallingIdentity();
7460            try {
7461                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7462                        + stackId + " toTop=" + toTop);
7463                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7464            } finally {
7465                Binder.restoreCallingIdentity(ident);
7466            }
7467        }
7468    }
7469
7470    @Override
7471    public void resizeStack(int stackBoxId, Rect bounds) {
7472        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7473                "resizeStackBox()");
7474        long ident = Binder.clearCallingIdentity();
7475        try {
7476            mWindowManager.resizeStack(stackBoxId, bounds);
7477        } finally {
7478            Binder.restoreCallingIdentity(ident);
7479        }
7480    }
7481
7482    @Override
7483    public List<StackInfo> getAllStackInfos() {
7484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7485                "getAllStackInfos()");
7486        long ident = Binder.clearCallingIdentity();
7487        try {
7488            synchronized (this) {
7489                return mStackSupervisor.getAllStackInfosLocked();
7490            }
7491        } finally {
7492            Binder.restoreCallingIdentity(ident);
7493        }
7494    }
7495
7496    @Override
7497    public StackInfo getStackInfo(int stackId) {
7498        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7499                "getStackInfo()");
7500        long ident = Binder.clearCallingIdentity();
7501        try {
7502            synchronized (this) {
7503                return mStackSupervisor.getStackInfoLocked(stackId);
7504            }
7505        } finally {
7506            Binder.restoreCallingIdentity(ident);
7507        }
7508    }
7509
7510    @Override
7511    public boolean isInHomeStack(int taskId) {
7512        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7513                "getStackInfo()");
7514        long ident = Binder.clearCallingIdentity();
7515        try {
7516            synchronized (this) {
7517                TaskRecord tr = recentTaskForIdLocked(taskId);
7518                if (tr != null) {
7519                    return tr.stack.isHomeStack();
7520                }
7521            }
7522        } finally {
7523            Binder.restoreCallingIdentity(ident);
7524        }
7525        return false;
7526    }
7527
7528    @Override
7529    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7530        synchronized(this) {
7531            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7532        }
7533    }
7534
7535    private boolean isLockTaskAuthorized(ComponentName name) {
7536//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7537//                "startLockTaskMode()");
7538//        DevicePolicyManager dpm = (DevicePolicyManager)
7539//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7540//        return dpm != null && dpm.isLockTaskPermitted(name);
7541        return true;
7542    }
7543
7544    private void startLockTaskMode(TaskRecord task) {
7545        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7546            return;
7547        }
7548        long ident = Binder.clearCallingIdentity();
7549        try {
7550            synchronized (this) {
7551                // Since we lost lock on task, make sure it is still there.
7552                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7553                if (task != null) {
7554                    mStackSupervisor.setLockTaskModeLocked(task);
7555                }
7556            }
7557        } finally {
7558            Binder.restoreCallingIdentity(ident);
7559        }
7560    }
7561
7562    @Override
7563    public void startLockTaskMode(int taskId) {
7564        long ident = Binder.clearCallingIdentity();
7565        try {
7566            final TaskRecord task;
7567            synchronized (this) {
7568                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7569            }
7570            if (task != null) {
7571                startLockTaskMode(task);
7572            }
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public void startLockTaskMode(IBinder token) {
7580        long ident = Binder.clearCallingIdentity();
7581        try {
7582            final TaskRecord task;
7583            synchronized (this) {
7584                final ActivityRecord r = ActivityRecord.forToken(token);
7585                if (r == null) {
7586                    return;
7587                }
7588                task = r.task;
7589            }
7590            if (task != null) {
7591                startLockTaskMode(task);
7592            }
7593        } finally {
7594            Binder.restoreCallingIdentity(ident);
7595        }
7596    }
7597
7598    @Override
7599    public void stopLockTaskMode() {
7600//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7601//                "stopLockTaskMode()");
7602        synchronized (this) {
7603            mStackSupervisor.setLockTaskModeLocked(null);
7604        }
7605    }
7606
7607    @Override
7608    public boolean isInLockTaskMode() {
7609        synchronized (this) {
7610            return mStackSupervisor.isInLockTaskMode();
7611        }
7612    }
7613
7614    // =========================================================
7615    // CONTENT PROVIDERS
7616    // =========================================================
7617
7618    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7619        List<ProviderInfo> providers = null;
7620        try {
7621            providers = AppGlobals.getPackageManager().
7622                queryContentProviders(app.processName, app.uid,
7623                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7624        } catch (RemoteException ex) {
7625        }
7626        if (DEBUG_MU)
7627            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7628        int userId = app.userId;
7629        if (providers != null) {
7630            int N = providers.size();
7631            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7632            for (int i=0; i<N; i++) {
7633                ProviderInfo cpi =
7634                    (ProviderInfo)providers.get(i);
7635                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7636                        cpi.name, cpi.flags);
7637                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7638                    // This is a singleton provider, but a user besides the
7639                    // default user is asking to initialize a process it runs
7640                    // in...  well, no, it doesn't actually run in this process,
7641                    // it runs in the process of the default user.  Get rid of it.
7642                    providers.remove(i);
7643                    N--;
7644                    i--;
7645                    continue;
7646                }
7647
7648                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7649                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7650                if (cpr == null) {
7651                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7652                    mProviderMap.putProviderByClass(comp, cpr);
7653                }
7654                if (DEBUG_MU)
7655                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7656                app.pubProviders.put(cpi.name, cpr);
7657                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7658                    // Don't add this if it is a platform component that is marked
7659                    // to run in multiple processes, because this is actually
7660                    // part of the framework so doesn't make sense to track as a
7661                    // separate apk in the process.
7662                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7663                }
7664                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7665            }
7666        }
7667        return providers;
7668    }
7669
7670    /**
7671     * Check if {@link ProcessRecord} has a possible chance at accessing the
7672     * given {@link ProviderInfo}. Final permission checking is always done
7673     * in {@link ContentProvider}.
7674     */
7675    private final String checkContentProviderPermissionLocked(
7676            ProviderInfo cpi, ProcessRecord r) {
7677        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7678        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7679        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7680                cpi.applicationInfo.uid, cpi.exported)
7681                == PackageManager.PERMISSION_GRANTED) {
7682            return null;
7683        }
7684        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7685                cpi.applicationInfo.uid, cpi.exported)
7686                == PackageManager.PERMISSION_GRANTED) {
7687            return null;
7688        }
7689
7690        PathPermission[] pps = cpi.pathPermissions;
7691        if (pps != null) {
7692            int i = pps.length;
7693            while (i > 0) {
7694                i--;
7695                PathPermission pp = pps[i];
7696                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7697                        cpi.applicationInfo.uid, cpi.exported)
7698                        == PackageManager.PERMISSION_GRANTED) {
7699                    return null;
7700                }
7701                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7702                        cpi.applicationInfo.uid, cpi.exported)
7703                        == PackageManager.PERMISSION_GRANTED) {
7704                    return null;
7705                }
7706            }
7707        }
7708
7709        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7710        if (perms != null) {
7711            for (GrantUri uri : perms.keySet()) {
7712                if (uri.uri.getAuthority().equals(cpi.authority)) {
7713                    return null;
7714                }
7715            }
7716        }
7717
7718        String msg;
7719        if (!cpi.exported) {
7720            msg = "Permission Denial: opening provider " + cpi.name
7721                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7722                    + ", uid=" + callingUid + ") that is not exported from uid "
7723                    + cpi.applicationInfo.uid;
7724        } else {
7725            msg = "Permission Denial: opening provider " + cpi.name
7726                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7727                    + ", uid=" + callingUid + ") requires "
7728                    + cpi.readPermission + " or " + cpi.writePermission;
7729        }
7730        Slog.w(TAG, msg);
7731        return msg;
7732    }
7733
7734    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7735            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7736        if (r != null) {
7737            for (int i=0; i<r.conProviders.size(); i++) {
7738                ContentProviderConnection conn = r.conProviders.get(i);
7739                if (conn.provider == cpr) {
7740                    if (DEBUG_PROVIDER) Slog.v(TAG,
7741                            "Adding provider requested by "
7742                            + r.processName + " from process "
7743                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7744                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7745                    if (stable) {
7746                        conn.stableCount++;
7747                        conn.numStableIncs++;
7748                    } else {
7749                        conn.unstableCount++;
7750                        conn.numUnstableIncs++;
7751                    }
7752                    return conn;
7753                }
7754            }
7755            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7756            if (stable) {
7757                conn.stableCount = 1;
7758                conn.numStableIncs = 1;
7759            } else {
7760                conn.unstableCount = 1;
7761                conn.numUnstableIncs = 1;
7762            }
7763            cpr.connections.add(conn);
7764            r.conProviders.add(conn);
7765            return conn;
7766        }
7767        cpr.addExternalProcessHandleLocked(externalProcessToken);
7768        return null;
7769    }
7770
7771    boolean decProviderCountLocked(ContentProviderConnection conn,
7772            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7773        if (conn != null) {
7774            cpr = conn.provider;
7775            if (DEBUG_PROVIDER) Slog.v(TAG,
7776                    "Removing provider requested by "
7777                    + conn.client.processName + " from process "
7778                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7779                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7780            if (stable) {
7781                conn.stableCount--;
7782            } else {
7783                conn.unstableCount--;
7784            }
7785            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7786                cpr.connections.remove(conn);
7787                conn.client.conProviders.remove(conn);
7788                return true;
7789            }
7790            return false;
7791        }
7792        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7793        return false;
7794    }
7795
7796    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7797            String name, IBinder token, boolean stable, int userId) {
7798        ContentProviderRecord cpr;
7799        ContentProviderConnection conn = null;
7800        ProviderInfo cpi = null;
7801
7802        synchronized(this) {
7803            ProcessRecord r = null;
7804            if (caller != null) {
7805                r = getRecordForAppLocked(caller);
7806                if (r == null) {
7807                    throw new SecurityException(
7808                            "Unable to find app for caller " + caller
7809                          + " (pid=" + Binder.getCallingPid()
7810                          + ") when getting content provider " + name);
7811                }
7812            }
7813
7814            // First check if this content provider has been published...
7815            cpr = mProviderMap.getProviderByName(name, userId);
7816            boolean providerRunning = cpr != null;
7817            if (providerRunning) {
7818                cpi = cpr.info;
7819                String msg;
7820                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7821                    throw new SecurityException(msg);
7822                }
7823
7824                if (r != null && cpr.canRunHere(r)) {
7825                    // This provider has been published or is in the process
7826                    // of being published...  but it is also allowed to run
7827                    // in the caller's process, so don't make a connection
7828                    // and just let the caller instantiate its own instance.
7829                    ContentProviderHolder holder = cpr.newHolder(null);
7830                    // don't give caller the provider object, it needs
7831                    // to make its own.
7832                    holder.provider = null;
7833                    return holder;
7834                }
7835
7836                final long origId = Binder.clearCallingIdentity();
7837
7838                // In this case the provider instance already exists, so we can
7839                // return it right away.
7840                conn = incProviderCountLocked(r, cpr, token, stable);
7841                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7842                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7843                        // If this is a perceptible app accessing the provider,
7844                        // make sure to count it as being accessed and thus
7845                        // back up on the LRU list.  This is good because
7846                        // content providers are often expensive to start.
7847                        updateLruProcessLocked(cpr.proc, false, null);
7848                    }
7849                }
7850
7851                if (cpr.proc != null) {
7852                    if (false) {
7853                        if (cpr.name.flattenToShortString().equals(
7854                                "com.android.providers.calendar/.CalendarProvider2")) {
7855                            Slog.v(TAG, "****************** KILLING "
7856                                + cpr.name.flattenToShortString());
7857                            Process.killProcess(cpr.proc.pid);
7858                        }
7859                    }
7860                    boolean success = updateOomAdjLocked(cpr.proc);
7861                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7862                    // NOTE: there is still a race here where a signal could be
7863                    // pending on the process even though we managed to update its
7864                    // adj level.  Not sure what to do about this, but at least
7865                    // the race is now smaller.
7866                    if (!success) {
7867                        // Uh oh...  it looks like the provider's process
7868                        // has been killed on us.  We need to wait for a new
7869                        // process to be started, and make sure its death
7870                        // doesn't kill our process.
7871                        Slog.i(TAG,
7872                                "Existing provider " + cpr.name.flattenToShortString()
7873                                + " is crashing; detaching " + r);
7874                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7875                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7876                        if (!lastRef) {
7877                            // This wasn't the last ref our process had on
7878                            // the provider...  we have now been killed, bail.
7879                            return null;
7880                        }
7881                        providerRunning = false;
7882                        conn = null;
7883                    }
7884                }
7885
7886                Binder.restoreCallingIdentity(origId);
7887            }
7888
7889            boolean singleton;
7890            if (!providerRunning) {
7891                try {
7892                    cpi = AppGlobals.getPackageManager().
7893                        resolveContentProvider(name,
7894                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7895                } catch (RemoteException ex) {
7896                }
7897                if (cpi == null) {
7898                    return null;
7899                }
7900                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7901                        cpi.name, cpi.flags);
7902                if (singleton) {
7903                    userId = 0;
7904                }
7905                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7906
7907                String msg;
7908                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7909                    throw new SecurityException(msg);
7910                }
7911
7912                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7913                        && !cpi.processName.equals("system")) {
7914                    // If this content provider does not run in the system
7915                    // process, and the system is not yet ready to run other
7916                    // processes, then fail fast instead of hanging.
7917                    throw new IllegalArgumentException(
7918                            "Attempt to launch content provider before system ready");
7919                }
7920
7921                // Make sure that the user who owns this provider is started.  If not,
7922                // we don't want to allow it to run.
7923                if (mStartedUsers.get(userId) == null) {
7924                    Slog.w(TAG, "Unable to launch app "
7925                            + cpi.applicationInfo.packageName + "/"
7926                            + cpi.applicationInfo.uid + " for provider "
7927                            + name + ": user " + userId + " is stopped");
7928                    return null;
7929                }
7930
7931                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7932                cpr = mProviderMap.getProviderByClass(comp, userId);
7933                final boolean firstClass = cpr == null;
7934                if (firstClass) {
7935                    try {
7936                        ApplicationInfo ai =
7937                            AppGlobals.getPackageManager().
7938                                getApplicationInfo(
7939                                        cpi.applicationInfo.packageName,
7940                                        STOCK_PM_FLAGS, userId);
7941                        if (ai == null) {
7942                            Slog.w(TAG, "No package info for content provider "
7943                                    + cpi.name);
7944                            return null;
7945                        }
7946                        ai = getAppInfoForUser(ai, userId);
7947                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7948                    } catch (RemoteException ex) {
7949                        // pm is in same process, this will never happen.
7950                    }
7951                }
7952
7953                if (r != null && cpr.canRunHere(r)) {
7954                    // If this is a multiprocess provider, then just return its
7955                    // info and allow the caller to instantiate it.  Only do
7956                    // this if the provider is the same user as the caller's
7957                    // process, or can run as root (so can be in any process).
7958                    return cpr.newHolder(null);
7959                }
7960
7961                if (DEBUG_PROVIDER) {
7962                    RuntimeException e = new RuntimeException("here");
7963                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7964                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7965                }
7966
7967                // This is single process, and our app is now connecting to it.
7968                // See if we are already in the process of launching this
7969                // provider.
7970                final int N = mLaunchingProviders.size();
7971                int i;
7972                for (i=0; i<N; i++) {
7973                    if (mLaunchingProviders.get(i) == cpr) {
7974                        break;
7975                    }
7976                }
7977
7978                // If the provider is not already being launched, then get it
7979                // started.
7980                if (i >= N) {
7981                    final long origId = Binder.clearCallingIdentity();
7982
7983                    try {
7984                        // Content provider is now in use, its package can't be stopped.
7985                        try {
7986                            AppGlobals.getPackageManager().setPackageStoppedState(
7987                                    cpr.appInfo.packageName, false, userId);
7988                        } catch (RemoteException e) {
7989                        } catch (IllegalArgumentException e) {
7990                            Slog.w(TAG, "Failed trying to unstop package "
7991                                    + cpr.appInfo.packageName + ": " + e);
7992                        }
7993
7994                        // Use existing process if already started
7995                        ProcessRecord proc = getProcessRecordLocked(
7996                                cpi.processName, cpr.appInfo.uid, false);
7997                        if (proc != null && proc.thread != null) {
7998                            if (DEBUG_PROVIDER) {
7999                                Slog.d(TAG, "Installing in existing process " + proc);
8000                            }
8001                            proc.pubProviders.put(cpi.name, cpr);
8002                            try {
8003                                proc.thread.scheduleInstallProvider(cpi);
8004                            } catch (RemoteException e) {
8005                            }
8006                        } else {
8007                            proc = startProcessLocked(cpi.processName,
8008                                    cpr.appInfo, false, 0, "content provider",
8009                                    new ComponentName(cpi.applicationInfo.packageName,
8010                                            cpi.name), false, false, false);
8011                            if (proc == null) {
8012                                Slog.w(TAG, "Unable to launch app "
8013                                        + cpi.applicationInfo.packageName + "/"
8014                                        + cpi.applicationInfo.uid + " for provider "
8015                                        + name + ": process is bad");
8016                                return null;
8017                            }
8018                        }
8019                        cpr.launchingApp = proc;
8020                        mLaunchingProviders.add(cpr);
8021                    } finally {
8022                        Binder.restoreCallingIdentity(origId);
8023                    }
8024                }
8025
8026                // Make sure the provider is published (the same provider class
8027                // may be published under multiple names).
8028                if (firstClass) {
8029                    mProviderMap.putProviderByClass(comp, cpr);
8030                }
8031
8032                mProviderMap.putProviderByName(name, cpr);
8033                conn = incProviderCountLocked(r, cpr, token, stable);
8034                if (conn != null) {
8035                    conn.waiting = true;
8036                }
8037            }
8038        }
8039
8040        // Wait for the provider to be published...
8041        synchronized (cpr) {
8042            while (cpr.provider == null) {
8043                if (cpr.launchingApp == null) {
8044                    Slog.w(TAG, "Unable to launch app "
8045                            + cpi.applicationInfo.packageName + "/"
8046                            + cpi.applicationInfo.uid + " for provider "
8047                            + name + ": launching app became null");
8048                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8049                            UserHandle.getUserId(cpi.applicationInfo.uid),
8050                            cpi.applicationInfo.packageName,
8051                            cpi.applicationInfo.uid, name);
8052                    return null;
8053                }
8054                try {
8055                    if (DEBUG_MU) {
8056                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8057                                + cpr.launchingApp);
8058                    }
8059                    if (conn != null) {
8060                        conn.waiting = true;
8061                    }
8062                    cpr.wait();
8063                } catch (InterruptedException ex) {
8064                } finally {
8065                    if (conn != null) {
8066                        conn.waiting = false;
8067                    }
8068                }
8069            }
8070        }
8071        return cpr != null ? cpr.newHolder(conn) : null;
8072    }
8073
8074    public final ContentProviderHolder getContentProvider(
8075            IApplicationThread caller, String name, int userId, boolean stable) {
8076        enforceNotIsolatedCaller("getContentProvider");
8077        if (caller == null) {
8078            String msg = "null IApplicationThread when getting content provider "
8079                    + name;
8080            Slog.w(TAG, msg);
8081            throw new SecurityException(msg);
8082        }
8083
8084        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8085                false, true, "getContentProvider", null);
8086        return getContentProviderImpl(caller, name, null, stable, userId);
8087    }
8088
8089    public ContentProviderHolder getContentProviderExternal(
8090            String name, int userId, IBinder token) {
8091        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8092            "Do not have permission in call getContentProviderExternal()");
8093        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8094                false, true, "getContentProvider", null);
8095        return getContentProviderExternalUnchecked(name, token, userId);
8096    }
8097
8098    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8099            IBinder token, int userId) {
8100        return getContentProviderImpl(null, name, token, true, userId);
8101    }
8102
8103    /**
8104     * Drop a content provider from a ProcessRecord's bookkeeping
8105     */
8106    public void removeContentProvider(IBinder connection, boolean stable) {
8107        enforceNotIsolatedCaller("removeContentProvider");
8108        long ident = Binder.clearCallingIdentity();
8109        try {
8110            synchronized (this) {
8111                ContentProviderConnection conn;
8112                try {
8113                    conn = (ContentProviderConnection)connection;
8114                } catch (ClassCastException e) {
8115                    String msg ="removeContentProvider: " + connection
8116                            + " not a ContentProviderConnection";
8117                    Slog.w(TAG, msg);
8118                    throw new IllegalArgumentException(msg);
8119                }
8120                if (conn == null) {
8121                    throw new NullPointerException("connection is null");
8122                }
8123                if (decProviderCountLocked(conn, null, null, stable)) {
8124                    updateOomAdjLocked();
8125                }
8126            }
8127        } finally {
8128            Binder.restoreCallingIdentity(ident);
8129        }
8130    }
8131
8132    public void removeContentProviderExternal(String name, IBinder token) {
8133        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8134            "Do not have permission in call removeContentProviderExternal()");
8135        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8136    }
8137
8138    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8139        synchronized (this) {
8140            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8141            if(cpr == null) {
8142                //remove from mProvidersByClass
8143                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8144                return;
8145            }
8146
8147            //update content provider record entry info
8148            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8149            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8150            if (localCpr.hasExternalProcessHandles()) {
8151                if (localCpr.removeExternalProcessHandleLocked(token)) {
8152                    updateOomAdjLocked();
8153                } else {
8154                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8155                            + " with no external reference for token: "
8156                            + token + ".");
8157                }
8158            } else {
8159                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8160                        + " with no external references.");
8161            }
8162        }
8163    }
8164
8165    public final void publishContentProviders(IApplicationThread caller,
8166            List<ContentProviderHolder> providers) {
8167        if (providers == null) {
8168            return;
8169        }
8170
8171        enforceNotIsolatedCaller("publishContentProviders");
8172        synchronized (this) {
8173            final ProcessRecord r = getRecordForAppLocked(caller);
8174            if (DEBUG_MU)
8175                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8176            if (r == null) {
8177                throw new SecurityException(
8178                        "Unable to find app for caller " + caller
8179                      + " (pid=" + Binder.getCallingPid()
8180                      + ") when publishing content providers");
8181            }
8182
8183            final long origId = Binder.clearCallingIdentity();
8184
8185            final int N = providers.size();
8186            for (int i=0; i<N; i++) {
8187                ContentProviderHolder src = providers.get(i);
8188                if (src == null || src.info == null || src.provider == null) {
8189                    continue;
8190                }
8191                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8192                if (DEBUG_MU)
8193                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8194                if (dst != null) {
8195                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8196                    mProviderMap.putProviderByClass(comp, dst);
8197                    String names[] = dst.info.authority.split(";");
8198                    for (int j = 0; j < names.length; j++) {
8199                        mProviderMap.putProviderByName(names[j], dst);
8200                    }
8201
8202                    int NL = mLaunchingProviders.size();
8203                    int j;
8204                    for (j=0; j<NL; j++) {
8205                        if (mLaunchingProviders.get(j) == dst) {
8206                            mLaunchingProviders.remove(j);
8207                            j--;
8208                            NL--;
8209                        }
8210                    }
8211                    synchronized (dst) {
8212                        dst.provider = src.provider;
8213                        dst.proc = r;
8214                        dst.notifyAll();
8215                    }
8216                    updateOomAdjLocked(r);
8217                }
8218            }
8219
8220            Binder.restoreCallingIdentity(origId);
8221        }
8222    }
8223
8224    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8225        ContentProviderConnection conn;
8226        try {
8227            conn = (ContentProviderConnection)connection;
8228        } catch (ClassCastException e) {
8229            String msg ="refContentProvider: " + connection
8230                    + " not a ContentProviderConnection";
8231            Slog.w(TAG, msg);
8232            throw new IllegalArgumentException(msg);
8233        }
8234        if (conn == null) {
8235            throw new NullPointerException("connection is null");
8236        }
8237
8238        synchronized (this) {
8239            if (stable > 0) {
8240                conn.numStableIncs += stable;
8241            }
8242            stable = conn.stableCount + stable;
8243            if (stable < 0) {
8244                throw new IllegalStateException("stableCount < 0: " + stable);
8245            }
8246
8247            if (unstable > 0) {
8248                conn.numUnstableIncs += unstable;
8249            }
8250            unstable = conn.unstableCount + unstable;
8251            if (unstable < 0) {
8252                throw new IllegalStateException("unstableCount < 0: " + unstable);
8253            }
8254
8255            if ((stable+unstable) <= 0) {
8256                throw new IllegalStateException("ref counts can't go to zero here: stable="
8257                        + stable + " unstable=" + unstable);
8258            }
8259            conn.stableCount = stable;
8260            conn.unstableCount = unstable;
8261            return !conn.dead;
8262        }
8263    }
8264
8265    public void unstableProviderDied(IBinder connection) {
8266        ContentProviderConnection conn;
8267        try {
8268            conn = (ContentProviderConnection)connection;
8269        } catch (ClassCastException e) {
8270            String msg ="refContentProvider: " + connection
8271                    + " not a ContentProviderConnection";
8272            Slog.w(TAG, msg);
8273            throw new IllegalArgumentException(msg);
8274        }
8275        if (conn == null) {
8276            throw new NullPointerException("connection is null");
8277        }
8278
8279        // Safely retrieve the content provider associated with the connection.
8280        IContentProvider provider;
8281        synchronized (this) {
8282            provider = conn.provider.provider;
8283        }
8284
8285        if (provider == null) {
8286            // Um, yeah, we're way ahead of you.
8287            return;
8288        }
8289
8290        // Make sure the caller is being honest with us.
8291        if (provider.asBinder().pingBinder()) {
8292            // Er, no, still looks good to us.
8293            synchronized (this) {
8294                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8295                        + " says " + conn + " died, but we don't agree");
8296                return;
8297            }
8298        }
8299
8300        // Well look at that!  It's dead!
8301        synchronized (this) {
8302            if (conn.provider.provider != provider) {
8303                // But something changed...  good enough.
8304                return;
8305            }
8306
8307            ProcessRecord proc = conn.provider.proc;
8308            if (proc == null || proc.thread == null) {
8309                // Seems like the process is already cleaned up.
8310                return;
8311            }
8312
8313            // As far as we're concerned, this is just like receiving a
8314            // death notification...  just a bit prematurely.
8315            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8316                    + ") early provider death");
8317            final long ident = Binder.clearCallingIdentity();
8318            try {
8319                appDiedLocked(proc, proc.pid, proc.thread);
8320            } finally {
8321                Binder.restoreCallingIdentity(ident);
8322            }
8323        }
8324    }
8325
8326    @Override
8327    public void appNotRespondingViaProvider(IBinder connection) {
8328        enforceCallingPermission(
8329                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8330
8331        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8332        if (conn == null) {
8333            Slog.w(TAG, "ContentProviderConnection is null");
8334            return;
8335        }
8336
8337        final ProcessRecord host = conn.provider.proc;
8338        if (host == null) {
8339            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8340            return;
8341        }
8342
8343        final long token = Binder.clearCallingIdentity();
8344        try {
8345            appNotResponding(host, null, null, false, "ContentProvider not responding");
8346        } finally {
8347            Binder.restoreCallingIdentity(token);
8348        }
8349    }
8350
8351    public final void installSystemProviders() {
8352        List<ProviderInfo> providers;
8353        synchronized (this) {
8354            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8355            providers = generateApplicationProvidersLocked(app);
8356            if (providers != null) {
8357                for (int i=providers.size()-1; i>=0; i--) {
8358                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8359                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8360                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8361                                + ": not system .apk");
8362                        providers.remove(i);
8363                    }
8364                }
8365            }
8366        }
8367        if (providers != null) {
8368            mSystemThread.installSystemProviders(providers);
8369        }
8370
8371        mCoreSettingsObserver = new CoreSettingsObserver(this);
8372
8373        mUsageStatsService.monitorPackages();
8374    }
8375
8376    /**
8377     * Allows app to retrieve the MIME type of a URI without having permission
8378     * to access its content provider.
8379     *
8380     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8381     *
8382     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8383     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8384     */
8385    public String getProviderMimeType(Uri uri, int userId) {
8386        enforceNotIsolatedCaller("getProviderMimeType");
8387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8388                userId, false, true, "getProviderMimeType", null);
8389        final String name = uri.getAuthority();
8390        final long ident = Binder.clearCallingIdentity();
8391        ContentProviderHolder holder = null;
8392
8393        try {
8394            holder = getContentProviderExternalUnchecked(name, null, userId);
8395            if (holder != null) {
8396                return holder.provider.getType(uri);
8397            }
8398        } catch (RemoteException e) {
8399            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8400            return null;
8401        } finally {
8402            if (holder != null) {
8403                removeContentProviderExternalUnchecked(name, null, userId);
8404            }
8405            Binder.restoreCallingIdentity(ident);
8406        }
8407
8408        return null;
8409    }
8410
8411    // =========================================================
8412    // GLOBAL MANAGEMENT
8413    // =========================================================
8414
8415    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8416            boolean isolated) {
8417        String proc = customProcess != null ? customProcess : info.processName;
8418        BatteryStatsImpl.Uid.Proc ps = null;
8419        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8420        int uid = info.uid;
8421        if (isolated) {
8422            int userId = UserHandle.getUserId(uid);
8423            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8424            while (true) {
8425                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8426                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8427                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8428                }
8429                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8430                mNextIsolatedProcessUid++;
8431                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8432                    // No process for this uid, use it.
8433                    break;
8434                }
8435                stepsLeft--;
8436                if (stepsLeft <= 0) {
8437                    return null;
8438                }
8439            }
8440        }
8441        return new ProcessRecord(stats, info, proc, uid);
8442    }
8443
8444    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8445        ProcessRecord app;
8446        if (!isolated) {
8447            app = getProcessRecordLocked(info.processName, info.uid, true);
8448        } else {
8449            app = null;
8450        }
8451
8452        if (app == null) {
8453            app = newProcessRecordLocked(info, null, isolated);
8454            mProcessNames.put(info.processName, app.uid, app);
8455            if (isolated) {
8456                mIsolatedProcesses.put(app.uid, app);
8457            }
8458            updateLruProcessLocked(app, false, null);
8459            updateOomAdjLocked();
8460        }
8461
8462        // This package really, really can not be stopped.
8463        try {
8464            AppGlobals.getPackageManager().setPackageStoppedState(
8465                    info.packageName, false, UserHandle.getUserId(app.uid));
8466        } catch (RemoteException e) {
8467        } catch (IllegalArgumentException e) {
8468            Slog.w(TAG, "Failed trying to unstop package "
8469                    + info.packageName + ": " + e);
8470        }
8471
8472        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8473                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8474            app.persistent = true;
8475            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8476        }
8477        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8478            mPersistentStartingProcesses.add(app);
8479            startProcessLocked(app, "added application", app.processName);
8480        }
8481
8482        return app;
8483    }
8484
8485    public void unhandledBack() {
8486        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8487                "unhandledBack()");
8488
8489        synchronized(this) {
8490            final long origId = Binder.clearCallingIdentity();
8491            try {
8492                getFocusedStack().unhandledBackLocked();
8493            } finally {
8494                Binder.restoreCallingIdentity(origId);
8495            }
8496        }
8497    }
8498
8499    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8500        enforceNotIsolatedCaller("openContentUri");
8501        final int userId = UserHandle.getCallingUserId();
8502        String name = uri.getAuthority();
8503        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8504        ParcelFileDescriptor pfd = null;
8505        if (cph != null) {
8506            // We record the binder invoker's uid in thread-local storage before
8507            // going to the content provider to open the file.  Later, in the code
8508            // that handles all permissions checks, we look for this uid and use
8509            // that rather than the Activity Manager's own uid.  The effect is that
8510            // we do the check against the caller's permissions even though it looks
8511            // to the content provider like the Activity Manager itself is making
8512            // the request.
8513            sCallerIdentity.set(new Identity(
8514                    Binder.getCallingPid(), Binder.getCallingUid()));
8515            try {
8516                pfd = cph.provider.openFile(null, uri, "r", null);
8517            } catch (FileNotFoundException e) {
8518                // do nothing; pfd will be returned null
8519            } finally {
8520                // Ensure that whatever happens, we clean up the identity state
8521                sCallerIdentity.remove();
8522            }
8523
8524            // We've got the fd now, so we're done with the provider.
8525            removeContentProviderExternalUnchecked(name, null, userId);
8526        } else {
8527            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8528        }
8529        return pfd;
8530    }
8531
8532    // Actually is sleeping or shutting down or whatever else in the future
8533    // is an inactive state.
8534    public boolean isSleepingOrShuttingDown() {
8535        return mSleeping || mShuttingDown;
8536    }
8537
8538    public boolean isSleeping() {
8539        return mSleeping;
8540    }
8541
8542    void goingToSleep() {
8543        synchronized(this) {
8544            mWentToSleep = true;
8545            updateEventDispatchingLocked();
8546            goToSleepIfNeededLocked();
8547        }
8548    }
8549
8550    void finishRunningVoiceLocked() {
8551        if (mRunningVoice) {
8552            mRunningVoice = false;
8553            goToSleepIfNeededLocked();
8554        }
8555    }
8556
8557    void goToSleepIfNeededLocked() {
8558        if (mWentToSleep && !mRunningVoice) {
8559            if (!mSleeping) {
8560                mSleeping = true;
8561                mStackSupervisor.goingToSleepLocked();
8562
8563                // Initialize the wake times of all processes.
8564                checkExcessivePowerUsageLocked(false);
8565                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8566                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8567                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8568            }
8569        }
8570    }
8571
8572    @Override
8573    public boolean shutdown(int timeout) {
8574        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8575                != PackageManager.PERMISSION_GRANTED) {
8576            throw new SecurityException("Requires permission "
8577                    + android.Manifest.permission.SHUTDOWN);
8578        }
8579
8580        boolean timedout = false;
8581
8582        synchronized(this) {
8583            mShuttingDown = true;
8584            updateEventDispatchingLocked();
8585            timedout = mStackSupervisor.shutdownLocked(timeout);
8586        }
8587
8588        mAppOpsService.shutdown();
8589        mUsageStatsService.shutdown();
8590        mBatteryStatsService.shutdown();
8591        synchronized (this) {
8592            mProcessStats.shutdownLocked();
8593        }
8594
8595        return timedout;
8596    }
8597
8598    public final void activitySlept(IBinder token) {
8599        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8600
8601        final long origId = Binder.clearCallingIdentity();
8602
8603        synchronized (this) {
8604            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8605            if (r != null) {
8606                mStackSupervisor.activitySleptLocked(r);
8607            }
8608        }
8609
8610        Binder.restoreCallingIdentity(origId);
8611    }
8612
8613    void logLockScreen(String msg) {
8614        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8615                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8616                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8617                mStackSupervisor.mDismissKeyguardOnNextActivity);
8618    }
8619
8620    private void comeOutOfSleepIfNeededLocked() {
8621        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8622            if (mSleeping) {
8623                mSleeping = false;
8624                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8625            }
8626        }
8627    }
8628
8629    void wakingUp() {
8630        synchronized(this) {
8631            mWentToSleep = false;
8632            updateEventDispatchingLocked();
8633            comeOutOfSleepIfNeededLocked();
8634        }
8635    }
8636
8637    void startRunningVoiceLocked() {
8638        if (!mRunningVoice) {
8639            mRunningVoice = true;
8640            comeOutOfSleepIfNeededLocked();
8641        }
8642    }
8643
8644    private void updateEventDispatchingLocked() {
8645        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8646    }
8647
8648    public void setLockScreenShown(boolean shown) {
8649        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8650                != PackageManager.PERMISSION_GRANTED) {
8651            throw new SecurityException("Requires permission "
8652                    + android.Manifest.permission.DEVICE_POWER);
8653        }
8654
8655        synchronized(this) {
8656            long ident = Binder.clearCallingIdentity();
8657            try {
8658                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8659                mLockScreenShown = shown;
8660                comeOutOfSleepIfNeededLocked();
8661            } finally {
8662                Binder.restoreCallingIdentity(ident);
8663            }
8664        }
8665    }
8666
8667    public void stopAppSwitches() {
8668        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8669                != PackageManager.PERMISSION_GRANTED) {
8670            throw new SecurityException("Requires permission "
8671                    + android.Manifest.permission.STOP_APP_SWITCHES);
8672        }
8673
8674        synchronized(this) {
8675            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8676                    + APP_SWITCH_DELAY_TIME;
8677            mDidAppSwitch = false;
8678            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8679            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8680            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8681        }
8682    }
8683
8684    public void resumeAppSwitches() {
8685        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8686                != PackageManager.PERMISSION_GRANTED) {
8687            throw new SecurityException("Requires permission "
8688                    + android.Manifest.permission.STOP_APP_SWITCHES);
8689        }
8690
8691        synchronized(this) {
8692            // Note that we don't execute any pending app switches... we will
8693            // let those wait until either the timeout, or the next start
8694            // activity request.
8695            mAppSwitchesAllowedTime = 0;
8696        }
8697    }
8698
8699    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8700            String name) {
8701        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8702            return true;
8703        }
8704
8705        final int perm = checkComponentPermission(
8706                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8707                callingUid, -1, true);
8708        if (perm == PackageManager.PERMISSION_GRANTED) {
8709            return true;
8710        }
8711
8712        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8713        return false;
8714    }
8715
8716    public void setDebugApp(String packageName, boolean waitForDebugger,
8717            boolean persistent) {
8718        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8719                "setDebugApp()");
8720
8721        long ident = Binder.clearCallingIdentity();
8722        try {
8723            // Note that this is not really thread safe if there are multiple
8724            // callers into it at the same time, but that's not a situation we
8725            // care about.
8726            if (persistent) {
8727                final ContentResolver resolver = mContext.getContentResolver();
8728                Settings.Global.putString(
8729                    resolver, Settings.Global.DEBUG_APP,
8730                    packageName);
8731                Settings.Global.putInt(
8732                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8733                    waitForDebugger ? 1 : 0);
8734            }
8735
8736            synchronized (this) {
8737                if (!persistent) {
8738                    mOrigDebugApp = mDebugApp;
8739                    mOrigWaitForDebugger = mWaitForDebugger;
8740                }
8741                mDebugApp = packageName;
8742                mWaitForDebugger = waitForDebugger;
8743                mDebugTransient = !persistent;
8744                if (packageName != null) {
8745                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8746                            false, UserHandle.USER_ALL, "set debug app");
8747                }
8748            }
8749        } finally {
8750            Binder.restoreCallingIdentity(ident);
8751        }
8752    }
8753
8754    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8755        synchronized (this) {
8756            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8757            if (!isDebuggable) {
8758                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8759                    throw new SecurityException("Process not debuggable: " + app.packageName);
8760                }
8761            }
8762
8763            mOpenGlTraceApp = processName;
8764        }
8765    }
8766
8767    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8768            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8769        synchronized (this) {
8770            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8771            if (!isDebuggable) {
8772                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8773                    throw new SecurityException("Process not debuggable: " + app.packageName);
8774                }
8775            }
8776            mProfileApp = processName;
8777            mProfileFile = profileFile;
8778            if (mProfileFd != null) {
8779                try {
8780                    mProfileFd.close();
8781                } catch (IOException e) {
8782                }
8783                mProfileFd = null;
8784            }
8785            mProfileFd = profileFd;
8786            mProfileType = 0;
8787            mAutoStopProfiler = autoStopProfiler;
8788        }
8789    }
8790
8791    @Override
8792    public void setAlwaysFinish(boolean enabled) {
8793        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8794                "setAlwaysFinish()");
8795
8796        Settings.Global.putInt(
8797                mContext.getContentResolver(),
8798                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8799
8800        synchronized (this) {
8801            mAlwaysFinishActivities = enabled;
8802        }
8803    }
8804
8805    @Override
8806    public void setActivityController(IActivityController controller) {
8807        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8808                "setActivityController()");
8809        synchronized (this) {
8810            mController = controller;
8811            Watchdog.getInstance().setActivityController(controller);
8812        }
8813    }
8814
8815    @Override
8816    public void setUserIsMonkey(boolean userIsMonkey) {
8817        synchronized (this) {
8818            synchronized (mPidsSelfLocked) {
8819                final int callingPid = Binder.getCallingPid();
8820                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8821                if (precessRecord == null) {
8822                    throw new SecurityException("Unknown process: " + callingPid);
8823                }
8824                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8825                    throw new SecurityException("Only an instrumentation process "
8826                            + "with a UiAutomation can call setUserIsMonkey");
8827                }
8828            }
8829            mUserIsMonkey = userIsMonkey;
8830        }
8831    }
8832
8833    @Override
8834    public boolean isUserAMonkey() {
8835        synchronized (this) {
8836            // If there is a controller also implies the user is a monkey.
8837            return (mUserIsMonkey || mController != null);
8838        }
8839    }
8840
8841    public void requestBugReport() {
8842        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8843        SystemProperties.set("ctl.start", "bugreport");
8844    }
8845
8846    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8847        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8848    }
8849
8850    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8851        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8852            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8853        }
8854        return KEY_DISPATCHING_TIMEOUT;
8855    }
8856
8857    @Override
8858    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8859        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8860                != PackageManager.PERMISSION_GRANTED) {
8861            throw new SecurityException("Requires permission "
8862                    + android.Manifest.permission.FILTER_EVENTS);
8863        }
8864        ProcessRecord proc;
8865        long timeout;
8866        synchronized (this) {
8867            synchronized (mPidsSelfLocked) {
8868                proc = mPidsSelfLocked.get(pid);
8869            }
8870            timeout = getInputDispatchingTimeoutLocked(proc);
8871        }
8872
8873        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8874            return -1;
8875        }
8876
8877        return timeout;
8878    }
8879
8880    /**
8881     * Handle input dispatching timeouts.
8882     * Returns whether input dispatching should be aborted or not.
8883     */
8884    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8885            final ActivityRecord activity, final ActivityRecord parent,
8886            final boolean aboveSystem, String reason) {
8887        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8888                != PackageManager.PERMISSION_GRANTED) {
8889            throw new SecurityException("Requires permission "
8890                    + android.Manifest.permission.FILTER_EVENTS);
8891        }
8892
8893        final String annotation;
8894        if (reason == null) {
8895            annotation = "Input dispatching timed out";
8896        } else {
8897            annotation = "Input dispatching timed out (" + reason + ")";
8898        }
8899
8900        if (proc != null) {
8901            synchronized (this) {
8902                if (proc.debugging) {
8903                    return false;
8904                }
8905
8906                if (mDidDexOpt) {
8907                    // Give more time since we were dexopting.
8908                    mDidDexOpt = false;
8909                    return false;
8910                }
8911
8912                if (proc.instrumentationClass != null) {
8913                    Bundle info = new Bundle();
8914                    info.putString("shortMsg", "keyDispatchingTimedOut");
8915                    info.putString("longMsg", annotation);
8916                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8917                    return true;
8918                }
8919            }
8920            mHandler.post(new Runnable() {
8921                @Override
8922                public void run() {
8923                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8924                }
8925            });
8926        }
8927
8928        return true;
8929    }
8930
8931    public Bundle getAssistContextExtras(int requestType) {
8932        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8933                "getAssistContextExtras()");
8934        PendingAssistExtras pae;
8935        Bundle extras = new Bundle();
8936        synchronized (this) {
8937            ActivityRecord activity = getFocusedStack().mResumedActivity;
8938            if (activity == null) {
8939                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8940                return null;
8941            }
8942            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8943            if (activity.app == null || activity.app.thread == null) {
8944                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8945                return extras;
8946            }
8947            if (activity.app.pid == Binder.getCallingPid()) {
8948                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8949                return extras;
8950            }
8951            pae = new PendingAssistExtras(activity);
8952            try {
8953                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8954                        requestType);
8955                mPendingAssistExtras.add(pae);
8956                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8957            } catch (RemoteException e) {
8958                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8959                return extras;
8960            }
8961        }
8962        synchronized (pae) {
8963            while (!pae.haveResult) {
8964                try {
8965                    pae.wait();
8966                } catch (InterruptedException e) {
8967                }
8968            }
8969            if (pae.result != null) {
8970                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8971            }
8972        }
8973        synchronized (this) {
8974            mPendingAssistExtras.remove(pae);
8975            mHandler.removeCallbacks(pae);
8976        }
8977        return extras;
8978    }
8979
8980    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8981        PendingAssistExtras pae = (PendingAssistExtras)token;
8982        synchronized (pae) {
8983            pae.result = extras;
8984            pae.haveResult = true;
8985            pae.notifyAll();
8986        }
8987    }
8988
8989    public void registerProcessObserver(IProcessObserver observer) {
8990        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8991                "registerProcessObserver()");
8992        synchronized (this) {
8993            mProcessObservers.register(observer);
8994        }
8995    }
8996
8997    @Override
8998    public void unregisterProcessObserver(IProcessObserver observer) {
8999        synchronized (this) {
9000            mProcessObservers.unregister(observer);
9001        }
9002    }
9003
9004    @Override
9005    public boolean convertFromTranslucent(IBinder token) {
9006        final long origId = Binder.clearCallingIdentity();
9007        try {
9008            synchronized (this) {
9009                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9010                if (r == null) {
9011                    return false;
9012                }
9013                if (r.changeWindowTranslucency(true)) {
9014                    mWindowManager.setAppFullscreen(token, true);
9015                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9016                    return true;
9017                }
9018                return false;
9019            }
9020        } finally {
9021            Binder.restoreCallingIdentity(origId);
9022        }
9023    }
9024
9025    @Override
9026    public boolean convertToTranslucent(IBinder token) {
9027        final long origId = Binder.clearCallingIdentity();
9028        try {
9029            synchronized (this) {
9030                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9031                if (r == null) {
9032                    return false;
9033                }
9034                if (r.changeWindowTranslucency(false)) {
9035                    r.task.stack.convertToTranslucent(r);
9036                    mWindowManager.setAppFullscreen(token, false);
9037                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9038                    return true;
9039                }
9040                return false;
9041            }
9042        } finally {
9043            Binder.restoreCallingIdentity(origId);
9044        }
9045    }
9046
9047    @Override
9048    public void setImmersive(IBinder token, boolean immersive) {
9049        synchronized(this) {
9050            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9051            if (r == null) {
9052                throw new IllegalArgumentException();
9053            }
9054            r.immersive = immersive;
9055
9056            // update associated state if we're frontmost
9057            if (r == mFocusedActivity) {
9058                if (DEBUG_IMMERSIVE) {
9059                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9060                }
9061                applyUpdateLockStateLocked(r);
9062            }
9063        }
9064    }
9065
9066    @Override
9067    public boolean isImmersive(IBinder token) {
9068        synchronized (this) {
9069            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9070            if (r == null) {
9071                throw new IllegalArgumentException();
9072            }
9073            return r.immersive;
9074        }
9075    }
9076
9077    public boolean isTopActivityImmersive() {
9078        enforceNotIsolatedCaller("startActivity");
9079        synchronized (this) {
9080            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9081            return (r != null) ? r.immersive : false;
9082        }
9083    }
9084
9085    public final void enterSafeMode() {
9086        synchronized(this) {
9087            // It only makes sense to do this before the system is ready
9088            // and started launching other packages.
9089            if (!mSystemReady) {
9090                try {
9091                    AppGlobals.getPackageManager().enterSafeMode();
9092                } catch (RemoteException e) {
9093                }
9094            }
9095
9096            mSafeMode = true;
9097        }
9098    }
9099
9100    public final void showSafeModeOverlay() {
9101        View v = LayoutInflater.from(mContext).inflate(
9102                com.android.internal.R.layout.safe_mode, null);
9103        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9104        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9105        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9106        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9107        lp.gravity = Gravity.BOTTOM | Gravity.START;
9108        lp.format = v.getBackground().getOpacity();
9109        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9110                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9111        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9112        ((WindowManager)mContext.getSystemService(
9113                Context.WINDOW_SERVICE)).addView(v, lp);
9114    }
9115
9116    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9117        if (!(sender instanceof PendingIntentRecord)) {
9118            return;
9119        }
9120        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9121        synchronized (stats) {
9122            if (mBatteryStatsService.isOnBattery()) {
9123                mBatteryStatsService.enforceCallingPermission();
9124                PendingIntentRecord rec = (PendingIntentRecord)sender;
9125                int MY_UID = Binder.getCallingUid();
9126                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9127                BatteryStatsImpl.Uid.Pkg pkg =
9128                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9129                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9130                pkg.incWakeupsLocked();
9131            }
9132        }
9133    }
9134
9135    public boolean killPids(int[] pids, String pReason, boolean secure) {
9136        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9137            throw new SecurityException("killPids only available to the system");
9138        }
9139        String reason = (pReason == null) ? "Unknown" : pReason;
9140        // XXX Note: don't acquire main activity lock here, because the window
9141        // manager calls in with its locks held.
9142
9143        boolean killed = false;
9144        synchronized (mPidsSelfLocked) {
9145            int[] types = new int[pids.length];
9146            int worstType = 0;
9147            for (int i=0; i<pids.length; i++) {
9148                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9149                if (proc != null) {
9150                    int type = proc.setAdj;
9151                    types[i] = type;
9152                    if (type > worstType) {
9153                        worstType = type;
9154                    }
9155                }
9156            }
9157
9158            // If the worst oom_adj is somewhere in the cached proc LRU range,
9159            // then constrain it so we will kill all cached procs.
9160            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9161                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9162                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9163            }
9164
9165            // If this is not a secure call, don't let it kill processes that
9166            // are important.
9167            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9168                worstType = ProcessList.SERVICE_ADJ;
9169            }
9170
9171            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9172            for (int i=0; i<pids.length; i++) {
9173                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9174                if (proc == null) {
9175                    continue;
9176                }
9177                int adj = proc.setAdj;
9178                if (adj >= worstType && !proc.killedByAm) {
9179                    killUnneededProcessLocked(proc, reason);
9180                    killed = true;
9181                }
9182            }
9183        }
9184        return killed;
9185    }
9186
9187    @Override
9188    public void killUid(int uid, String reason) {
9189        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9190            throw new SecurityException("killUid only available to the system");
9191        }
9192        synchronized (this) {
9193            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9194                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9195                    reason != null ? reason : "kill uid");
9196        }
9197    }
9198
9199    @Override
9200    public boolean killProcessesBelowForeground(String reason) {
9201        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9202            throw new SecurityException("killProcessesBelowForeground() only available to system");
9203        }
9204
9205        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9206    }
9207
9208    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9209        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9210            throw new SecurityException("killProcessesBelowAdj() only available to system");
9211        }
9212
9213        boolean killed = false;
9214        synchronized (mPidsSelfLocked) {
9215            final int size = mPidsSelfLocked.size();
9216            for (int i = 0; i < size; i++) {
9217                final int pid = mPidsSelfLocked.keyAt(i);
9218                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9219                if (proc == null) continue;
9220
9221                final int adj = proc.setAdj;
9222                if (adj > belowAdj && !proc.killedByAm) {
9223                    killUnneededProcessLocked(proc, reason);
9224                    killed = true;
9225                }
9226            }
9227        }
9228        return killed;
9229    }
9230
9231    @Override
9232    public void hang(final IBinder who, boolean allowRestart) {
9233        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9234                != PackageManager.PERMISSION_GRANTED) {
9235            throw new SecurityException("Requires permission "
9236                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9237        }
9238
9239        final IBinder.DeathRecipient death = new DeathRecipient() {
9240            @Override
9241            public void binderDied() {
9242                synchronized (this) {
9243                    notifyAll();
9244                }
9245            }
9246        };
9247
9248        try {
9249            who.linkToDeath(death, 0);
9250        } catch (RemoteException e) {
9251            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9252            return;
9253        }
9254
9255        synchronized (this) {
9256            Watchdog.getInstance().setAllowRestart(allowRestart);
9257            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9258            synchronized (death) {
9259                while (who.isBinderAlive()) {
9260                    try {
9261                        death.wait();
9262                    } catch (InterruptedException e) {
9263                    }
9264                }
9265            }
9266            Watchdog.getInstance().setAllowRestart(true);
9267        }
9268    }
9269
9270    @Override
9271    public void restart() {
9272        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9273                != PackageManager.PERMISSION_GRANTED) {
9274            throw new SecurityException("Requires permission "
9275                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9276        }
9277
9278        Log.i(TAG, "Sending shutdown broadcast...");
9279
9280        BroadcastReceiver br = new BroadcastReceiver() {
9281            @Override public void onReceive(Context context, Intent intent) {
9282                // Now the broadcast is done, finish up the low-level shutdown.
9283                Log.i(TAG, "Shutting down activity manager...");
9284                shutdown(10000);
9285                Log.i(TAG, "Shutdown complete, restarting!");
9286                Process.killProcess(Process.myPid());
9287                System.exit(10);
9288            }
9289        };
9290
9291        // First send the high-level shut down broadcast.
9292        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9293        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9294        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9295        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9296        mContext.sendOrderedBroadcastAsUser(intent,
9297                UserHandle.ALL, null, br, mHandler, 0, null, null);
9298        */
9299        br.onReceive(mContext, intent);
9300    }
9301
9302    private long getLowRamTimeSinceIdle(long now) {
9303        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9304    }
9305
9306    @Override
9307    public void performIdleMaintenance() {
9308        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9309                != PackageManager.PERMISSION_GRANTED) {
9310            throw new SecurityException("Requires permission "
9311                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9312        }
9313
9314        synchronized (this) {
9315            final long now = SystemClock.uptimeMillis();
9316            final long timeSinceLastIdle = now - mLastIdleTime;
9317            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9318            mLastIdleTime = now;
9319            mLowRamTimeSinceLastIdle = 0;
9320            if (mLowRamStartTime != 0) {
9321                mLowRamStartTime = now;
9322            }
9323
9324            StringBuilder sb = new StringBuilder(128);
9325            sb.append("Idle maintenance over ");
9326            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9327            sb.append(" low RAM for ");
9328            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9329            Slog.i(TAG, sb.toString());
9330
9331            // If at least 1/3 of our time since the last idle period has been spent
9332            // with RAM low, then we want to kill processes.
9333            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9334
9335            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9336                ProcessRecord proc = mLruProcesses.get(i);
9337                if (proc.notCachedSinceIdle) {
9338                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9339                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9340                        if (doKilling && proc.initialIdlePss != 0
9341                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9342                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9343                                    + " from " + proc.initialIdlePss + ")");
9344                        }
9345                    }
9346                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9347                    proc.notCachedSinceIdle = true;
9348                    proc.initialIdlePss = 0;
9349                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9350                            isSleeping(), now);
9351                }
9352            }
9353
9354            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9355            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9356        }
9357    }
9358
9359    private void retrieveSettings() {
9360        final ContentResolver resolver = mContext.getContentResolver();
9361        String debugApp = Settings.Global.getString(
9362            resolver, Settings.Global.DEBUG_APP);
9363        boolean waitForDebugger = Settings.Global.getInt(
9364            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9365        boolean alwaysFinishActivities = Settings.Global.getInt(
9366            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9367        boolean forceRtl = Settings.Global.getInt(
9368                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9369        // Transfer any global setting for forcing RTL layout, into a System Property
9370        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9371
9372        Configuration configuration = new Configuration();
9373        Settings.System.getConfiguration(resolver, configuration);
9374        if (forceRtl) {
9375            // This will take care of setting the correct layout direction flags
9376            configuration.setLayoutDirection(configuration.locale);
9377        }
9378
9379        synchronized (this) {
9380            mDebugApp = mOrigDebugApp = debugApp;
9381            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9382            mAlwaysFinishActivities = alwaysFinishActivities;
9383            // This happens before any activities are started, so we can
9384            // change mConfiguration in-place.
9385            updateConfigurationLocked(configuration, null, false, true);
9386            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9387        }
9388    }
9389
9390    public boolean testIsSystemReady() {
9391        // no need to synchronize(this) just to read & return the value
9392        return mSystemReady;
9393    }
9394
9395    private static File getCalledPreBootReceiversFile() {
9396        File dataDir = Environment.getDataDirectory();
9397        File systemDir = new File(dataDir, "system");
9398        File fname = new File(systemDir, "called_pre_boots.dat");
9399        return fname;
9400    }
9401
9402    static final int LAST_DONE_VERSION = 10000;
9403
9404    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9405        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9406        File file = getCalledPreBootReceiversFile();
9407        FileInputStream fis = null;
9408        try {
9409            fis = new FileInputStream(file);
9410            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9411            int fvers = dis.readInt();
9412            if (fvers == LAST_DONE_VERSION) {
9413                String vers = dis.readUTF();
9414                String codename = dis.readUTF();
9415                String build = dis.readUTF();
9416                if (android.os.Build.VERSION.RELEASE.equals(vers)
9417                        && android.os.Build.VERSION.CODENAME.equals(codename)
9418                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9419                    int num = dis.readInt();
9420                    while (num > 0) {
9421                        num--;
9422                        String pkg = dis.readUTF();
9423                        String cls = dis.readUTF();
9424                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9425                    }
9426                }
9427            }
9428        } catch (FileNotFoundException e) {
9429        } catch (IOException e) {
9430            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9431        } finally {
9432            if (fis != null) {
9433                try {
9434                    fis.close();
9435                } catch (IOException e) {
9436                }
9437            }
9438        }
9439        return lastDoneReceivers;
9440    }
9441
9442    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9443        File file = getCalledPreBootReceiversFile();
9444        FileOutputStream fos = null;
9445        DataOutputStream dos = null;
9446        try {
9447            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9448            fos = new FileOutputStream(file);
9449            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9450            dos.writeInt(LAST_DONE_VERSION);
9451            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9452            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9453            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9454            dos.writeInt(list.size());
9455            for (int i=0; i<list.size(); i++) {
9456                dos.writeUTF(list.get(i).getPackageName());
9457                dos.writeUTF(list.get(i).getClassName());
9458            }
9459        } catch (IOException e) {
9460            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9461            file.delete();
9462        } finally {
9463            FileUtils.sync(fos);
9464            if (dos != null) {
9465                try {
9466                    dos.close();
9467                } catch (IOException e) {
9468                    // TODO Auto-generated catch block
9469                    e.printStackTrace();
9470                }
9471            }
9472        }
9473    }
9474
9475    public void systemReady(final Runnable goingCallback) {
9476        synchronized(this) {
9477            if (mSystemReady) {
9478                if (goingCallback != null) goingCallback.run();
9479                return;
9480            }
9481
9482            // Check to see if there are any update receivers to run.
9483            if (!mDidUpdate) {
9484                if (mWaitingUpdate) {
9485                    return;
9486                }
9487                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9488                List<ResolveInfo> ris = null;
9489                try {
9490                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9491                            intent, null, 0, 0);
9492                } catch (RemoteException e) {
9493                }
9494                if (ris != null) {
9495                    for (int i=ris.size()-1; i>=0; i--) {
9496                        if ((ris.get(i).activityInfo.applicationInfo.flags
9497                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9498                            ris.remove(i);
9499                        }
9500                    }
9501                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9502
9503                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9504
9505                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9506                    for (int i=0; i<ris.size(); i++) {
9507                        ActivityInfo ai = ris.get(i).activityInfo;
9508                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9509                        if (lastDoneReceivers.contains(comp)) {
9510                            // We already did the pre boot receiver for this app with the current
9511                            // platform version, so don't do it again...
9512                            ris.remove(i);
9513                            i--;
9514                            // ...however, do keep it as one that has been done, so we don't
9515                            // forget about it when rewriting the file of last done receivers.
9516                            doneReceivers.add(comp);
9517                        }
9518                    }
9519
9520                    final int[] users = getUsersLocked();
9521                    for (int i=0; i<ris.size(); i++) {
9522                        ActivityInfo ai = ris.get(i).activityInfo;
9523                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9524                        doneReceivers.add(comp);
9525                        intent.setComponent(comp);
9526                        for (int j=0; j<users.length; j++) {
9527                            IIntentReceiver finisher = null;
9528                            if (i == ris.size()-1 && j == users.length-1) {
9529                                finisher = new IIntentReceiver.Stub() {
9530                                    public void performReceive(Intent intent, int resultCode,
9531                                            String data, Bundle extras, boolean ordered,
9532                                            boolean sticky, int sendingUser) {
9533                                        // The raw IIntentReceiver interface is called
9534                                        // with the AM lock held, so redispatch to
9535                                        // execute our code without the lock.
9536                                        mHandler.post(new Runnable() {
9537                                            public void run() {
9538                                                synchronized (ActivityManagerService.this) {
9539                                                    mDidUpdate = true;
9540                                                }
9541                                                writeLastDonePreBootReceivers(doneReceivers);
9542                                                showBootMessage(mContext.getText(
9543                                                        R.string.android_upgrading_complete),
9544                                                        false);
9545                                                systemReady(goingCallback);
9546                                            }
9547                                        });
9548                                    }
9549                                };
9550                            }
9551                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9552                                    + " for user " + users[j]);
9553                            broadcastIntentLocked(null, null, intent, null, finisher,
9554                                    0, null, null, null, AppOpsManager.OP_NONE,
9555                                    true, false, MY_PID, Process.SYSTEM_UID,
9556                                    users[j]);
9557                            if (finisher != null) {
9558                                mWaitingUpdate = true;
9559                            }
9560                        }
9561                    }
9562                }
9563                if (mWaitingUpdate) {
9564                    return;
9565                }
9566                mDidUpdate = true;
9567            }
9568
9569            mAppOpsService.systemReady();
9570            mSystemReady = true;
9571        }
9572
9573        ArrayList<ProcessRecord> procsToKill = null;
9574        synchronized(mPidsSelfLocked) {
9575            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9576                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9577                if (!isAllowedWhileBooting(proc.info)){
9578                    if (procsToKill == null) {
9579                        procsToKill = new ArrayList<ProcessRecord>();
9580                    }
9581                    procsToKill.add(proc);
9582                }
9583            }
9584        }
9585
9586        synchronized(this) {
9587            if (procsToKill != null) {
9588                for (int i=procsToKill.size()-1; i>=0; i--) {
9589                    ProcessRecord proc = procsToKill.get(i);
9590                    Slog.i(TAG, "Removing system update proc: " + proc);
9591                    removeProcessLocked(proc, true, false, "system update done");
9592                }
9593            }
9594
9595            // Now that we have cleaned up any update processes, we
9596            // are ready to start launching real processes and know that
9597            // we won't trample on them any more.
9598            mProcessesReady = true;
9599        }
9600
9601        Slog.i(TAG, "System now ready");
9602        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9603            SystemClock.uptimeMillis());
9604
9605        synchronized(this) {
9606            // Make sure we have no pre-ready processes sitting around.
9607
9608            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9609                ResolveInfo ri = mContext.getPackageManager()
9610                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9611                                STOCK_PM_FLAGS);
9612                CharSequence errorMsg = null;
9613                if (ri != null) {
9614                    ActivityInfo ai = ri.activityInfo;
9615                    ApplicationInfo app = ai.applicationInfo;
9616                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9617                        mTopAction = Intent.ACTION_FACTORY_TEST;
9618                        mTopData = null;
9619                        mTopComponent = new ComponentName(app.packageName,
9620                                ai.name);
9621                    } else {
9622                        errorMsg = mContext.getResources().getText(
9623                                com.android.internal.R.string.factorytest_not_system);
9624                    }
9625                } else {
9626                    errorMsg = mContext.getResources().getText(
9627                            com.android.internal.R.string.factorytest_no_action);
9628                }
9629                if (errorMsg != null) {
9630                    mTopAction = null;
9631                    mTopData = null;
9632                    mTopComponent = null;
9633                    Message msg = Message.obtain();
9634                    msg.what = SHOW_FACTORY_ERROR_MSG;
9635                    msg.getData().putCharSequence("msg", errorMsg);
9636                    mHandler.sendMessage(msg);
9637                }
9638            }
9639        }
9640
9641        retrieveSettings();
9642
9643        synchronized (this) {
9644            readGrantedUriPermissionsLocked();
9645        }
9646
9647        if (goingCallback != null) goingCallback.run();
9648
9649        mSystemServiceManager.startUser(mCurrentUserId);
9650
9651        synchronized (this) {
9652            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9653                try {
9654                    List apps = AppGlobals.getPackageManager().
9655                        getPersistentApplications(STOCK_PM_FLAGS);
9656                    if (apps != null) {
9657                        int N = apps.size();
9658                        int i;
9659                        for (i=0; i<N; i++) {
9660                            ApplicationInfo info
9661                                = (ApplicationInfo)apps.get(i);
9662                            if (info != null &&
9663                                    !info.packageName.equals("android")) {
9664                                addAppLocked(info, false);
9665                            }
9666                        }
9667                    }
9668                } catch (RemoteException ex) {
9669                    // pm is in same process, this will never happen.
9670                }
9671            }
9672
9673            // Start up initial activity.
9674            mBooting = true;
9675
9676            try {
9677                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9678                    Message msg = Message.obtain();
9679                    msg.what = SHOW_UID_ERROR_MSG;
9680                    mHandler.sendMessage(msg);
9681                }
9682            } catch (RemoteException e) {
9683            }
9684
9685            long ident = Binder.clearCallingIdentity();
9686            try {
9687                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9688                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9689                        | Intent.FLAG_RECEIVER_FOREGROUND);
9690                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9691                broadcastIntentLocked(null, null, intent,
9692                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9693                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9694                intent = new Intent(Intent.ACTION_USER_STARTING);
9695                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9696                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9697                broadcastIntentLocked(null, null, intent,
9698                        null, new IIntentReceiver.Stub() {
9699                            @Override
9700                            public void performReceive(Intent intent, int resultCode, String data,
9701                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9702                                    throws RemoteException {
9703                            }
9704                        }, 0, null, null,
9705                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9706                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9707            } catch (Throwable t) {
9708                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9709            } finally {
9710                Binder.restoreCallingIdentity(ident);
9711            }
9712            mStackSupervisor.resumeTopActivitiesLocked();
9713            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9714        }
9715    }
9716
9717    private boolean makeAppCrashingLocked(ProcessRecord app,
9718            String shortMsg, String longMsg, String stackTrace) {
9719        app.crashing = true;
9720        app.crashingReport = generateProcessError(app,
9721                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9722        startAppProblemLocked(app);
9723        app.stopFreezingAllLocked();
9724        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9725    }
9726
9727    private void makeAppNotRespondingLocked(ProcessRecord app,
9728            String activity, String shortMsg, String longMsg) {
9729        app.notResponding = true;
9730        app.notRespondingReport = generateProcessError(app,
9731                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9732                activity, shortMsg, longMsg, null);
9733        startAppProblemLocked(app);
9734        app.stopFreezingAllLocked();
9735    }
9736
9737    /**
9738     * Generate a process error record, suitable for attachment to a ProcessRecord.
9739     *
9740     * @param app The ProcessRecord in which the error occurred.
9741     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9742     *                      ActivityManager.AppErrorStateInfo
9743     * @param activity The activity associated with the crash, if known.
9744     * @param shortMsg Short message describing the crash.
9745     * @param longMsg Long message describing the crash.
9746     * @param stackTrace Full crash stack trace, may be null.
9747     *
9748     * @return Returns a fully-formed AppErrorStateInfo record.
9749     */
9750    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9751            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9752        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9753
9754        report.condition = condition;
9755        report.processName = app.processName;
9756        report.pid = app.pid;
9757        report.uid = app.info.uid;
9758        report.tag = activity;
9759        report.shortMsg = shortMsg;
9760        report.longMsg = longMsg;
9761        report.stackTrace = stackTrace;
9762
9763        return report;
9764    }
9765
9766    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9767        synchronized (this) {
9768            app.crashing = false;
9769            app.crashingReport = null;
9770            app.notResponding = false;
9771            app.notRespondingReport = null;
9772            if (app.anrDialog == fromDialog) {
9773                app.anrDialog = null;
9774            }
9775            if (app.waitDialog == fromDialog) {
9776                app.waitDialog = null;
9777            }
9778            if (app.pid > 0 && app.pid != MY_PID) {
9779                handleAppCrashLocked(app, null, null, null);
9780                killUnneededProcessLocked(app, "user request after error");
9781            }
9782        }
9783    }
9784
9785    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9786            String stackTrace) {
9787        long now = SystemClock.uptimeMillis();
9788
9789        Long crashTime;
9790        if (!app.isolated) {
9791            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9792        } else {
9793            crashTime = null;
9794        }
9795        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9796            // This process loses!
9797            Slog.w(TAG, "Process " + app.info.processName
9798                    + " has crashed too many times: killing!");
9799            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9800                    app.userId, app.info.processName, app.uid);
9801            mStackSupervisor.handleAppCrashLocked(app);
9802            if (!app.persistent) {
9803                // We don't want to start this process again until the user
9804                // explicitly does so...  but for persistent process, we really
9805                // need to keep it running.  If a persistent process is actually
9806                // repeatedly crashing, then badness for everyone.
9807                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9808                        app.info.processName);
9809                if (!app.isolated) {
9810                    // XXX We don't have a way to mark isolated processes
9811                    // as bad, since they don't have a peristent identity.
9812                    mBadProcesses.put(app.info.processName, app.uid,
9813                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9814                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9815                }
9816                app.bad = true;
9817                app.removed = true;
9818                // Don't let services in this process be restarted and potentially
9819                // annoy the user repeatedly.  Unless it is persistent, since those
9820                // processes run critical code.
9821                removeProcessLocked(app, false, false, "crash");
9822                mStackSupervisor.resumeTopActivitiesLocked();
9823                return false;
9824            }
9825            mStackSupervisor.resumeTopActivitiesLocked();
9826        } else {
9827            mStackSupervisor.finishTopRunningActivityLocked(app);
9828        }
9829
9830        // Bump up the crash count of any services currently running in the proc.
9831        for (int i=app.services.size()-1; i>=0; i--) {
9832            // Any services running in the application need to be placed
9833            // back in the pending list.
9834            ServiceRecord sr = app.services.valueAt(i);
9835            sr.crashCount++;
9836        }
9837
9838        // If the crashing process is what we consider to be the "home process" and it has been
9839        // replaced by a third-party app, clear the package preferred activities from packages
9840        // with a home activity running in the process to prevent a repeatedly crashing app
9841        // from blocking the user to manually clear the list.
9842        final ArrayList<ActivityRecord> activities = app.activities;
9843        if (app == mHomeProcess && activities.size() > 0
9844                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9845            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9846                final ActivityRecord r = activities.get(activityNdx);
9847                if (r.isHomeActivity()) {
9848                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9849                    try {
9850                        ActivityThread.getPackageManager()
9851                                .clearPackagePreferredActivities(r.packageName);
9852                    } catch (RemoteException c) {
9853                        // pm is in same process, this will never happen.
9854                    }
9855                }
9856            }
9857        }
9858
9859        if (!app.isolated) {
9860            // XXX Can't keep track of crash times for isolated processes,
9861            // because they don't have a perisistent identity.
9862            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9863        }
9864
9865        return true;
9866    }
9867
9868    void startAppProblemLocked(ProcessRecord app) {
9869        if (app.userId == mCurrentUserId) {
9870            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9871                    mContext, app.info.packageName, app.info.flags);
9872        } else {
9873            // If this app is not running under the current user, then we
9874            // can't give it a report button because that would require
9875            // launching the report UI under a different user.
9876            app.errorReportReceiver = null;
9877        }
9878        skipCurrentReceiverLocked(app);
9879    }
9880
9881    void skipCurrentReceiverLocked(ProcessRecord app) {
9882        for (BroadcastQueue queue : mBroadcastQueues) {
9883            queue.skipCurrentReceiverLocked(app);
9884        }
9885    }
9886
9887    /**
9888     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9889     * The application process will exit immediately after this call returns.
9890     * @param app object of the crashing app, null for the system server
9891     * @param crashInfo describing the exception
9892     */
9893    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9894        ProcessRecord r = findAppProcess(app, "Crash");
9895        final String processName = app == null ? "system_server"
9896                : (r == null ? "unknown" : r.processName);
9897
9898        handleApplicationCrashInner("crash", r, processName, crashInfo);
9899    }
9900
9901    /* Native crash reporting uses this inner version because it needs to be somewhat
9902     * decoupled from the AM-managed cleanup lifecycle
9903     */
9904    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9905            ApplicationErrorReport.CrashInfo crashInfo) {
9906        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9907                UserHandle.getUserId(Binder.getCallingUid()), processName,
9908                r == null ? -1 : r.info.flags,
9909                crashInfo.exceptionClassName,
9910                crashInfo.exceptionMessage,
9911                crashInfo.throwFileName,
9912                crashInfo.throwLineNumber);
9913
9914        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9915
9916        crashApplication(r, crashInfo);
9917    }
9918
9919    public void handleApplicationStrictModeViolation(
9920            IBinder app,
9921            int violationMask,
9922            StrictMode.ViolationInfo info) {
9923        ProcessRecord r = findAppProcess(app, "StrictMode");
9924        if (r == null) {
9925            return;
9926        }
9927
9928        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9929            Integer stackFingerprint = info.hashCode();
9930            boolean logIt = true;
9931            synchronized (mAlreadyLoggedViolatedStacks) {
9932                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9933                    logIt = false;
9934                    // TODO: sub-sample into EventLog for these, with
9935                    // the info.durationMillis?  Then we'd get
9936                    // the relative pain numbers, without logging all
9937                    // the stack traces repeatedly.  We'd want to do
9938                    // likewise in the client code, which also does
9939                    // dup suppression, before the Binder call.
9940                } else {
9941                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9942                        mAlreadyLoggedViolatedStacks.clear();
9943                    }
9944                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9945                }
9946            }
9947            if (logIt) {
9948                logStrictModeViolationToDropBox(r, info);
9949            }
9950        }
9951
9952        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9953            AppErrorResult result = new AppErrorResult();
9954            synchronized (this) {
9955                final long origId = Binder.clearCallingIdentity();
9956
9957                Message msg = Message.obtain();
9958                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9959                HashMap<String, Object> data = new HashMap<String, Object>();
9960                data.put("result", result);
9961                data.put("app", r);
9962                data.put("violationMask", violationMask);
9963                data.put("info", info);
9964                msg.obj = data;
9965                mHandler.sendMessage(msg);
9966
9967                Binder.restoreCallingIdentity(origId);
9968            }
9969            int res = result.get();
9970            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9971        }
9972    }
9973
9974    // Depending on the policy in effect, there could be a bunch of
9975    // these in quick succession so we try to batch these together to
9976    // minimize disk writes, number of dropbox entries, and maximize
9977    // compression, by having more fewer, larger records.
9978    private void logStrictModeViolationToDropBox(
9979            ProcessRecord process,
9980            StrictMode.ViolationInfo info) {
9981        if (info == null) {
9982            return;
9983        }
9984        final boolean isSystemApp = process == null ||
9985                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9986                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9987        final String processName = process == null ? "unknown" : process.processName;
9988        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9989        final DropBoxManager dbox = (DropBoxManager)
9990                mContext.getSystemService(Context.DROPBOX_SERVICE);
9991
9992        // Exit early if the dropbox isn't configured to accept this report type.
9993        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9994
9995        boolean bufferWasEmpty;
9996        boolean needsFlush;
9997        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9998        synchronized (sb) {
9999            bufferWasEmpty = sb.length() == 0;
10000            appendDropBoxProcessHeaders(process, processName, sb);
10001            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10002            sb.append("System-App: ").append(isSystemApp).append("\n");
10003            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10004            if (info.violationNumThisLoop != 0) {
10005                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10006            }
10007            if (info.numAnimationsRunning != 0) {
10008                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10009            }
10010            if (info.broadcastIntentAction != null) {
10011                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10012            }
10013            if (info.durationMillis != -1) {
10014                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10015            }
10016            if (info.numInstances != -1) {
10017                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10018            }
10019            if (info.tags != null) {
10020                for (String tag : info.tags) {
10021                    sb.append("Span-Tag: ").append(tag).append("\n");
10022                }
10023            }
10024            sb.append("\n");
10025            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10026                sb.append(info.crashInfo.stackTrace);
10027            }
10028            sb.append("\n");
10029
10030            // Only buffer up to ~64k.  Various logging bits truncate
10031            // things at 128k.
10032            needsFlush = (sb.length() > 64 * 1024);
10033        }
10034
10035        // Flush immediately if the buffer's grown too large, or this
10036        // is a non-system app.  Non-system apps are isolated with a
10037        // different tag & policy and not batched.
10038        //
10039        // Batching is useful during internal testing with
10040        // StrictMode settings turned up high.  Without batching,
10041        // thousands of separate files could be created on boot.
10042        if (!isSystemApp || needsFlush) {
10043            new Thread("Error dump: " + dropboxTag) {
10044                @Override
10045                public void run() {
10046                    String report;
10047                    synchronized (sb) {
10048                        report = sb.toString();
10049                        sb.delete(0, sb.length());
10050                        sb.trimToSize();
10051                    }
10052                    if (report.length() != 0) {
10053                        dbox.addText(dropboxTag, report);
10054                    }
10055                }
10056            }.start();
10057            return;
10058        }
10059
10060        // System app batching:
10061        if (!bufferWasEmpty) {
10062            // An existing dropbox-writing thread is outstanding, so
10063            // we don't need to start it up.  The existing thread will
10064            // catch the buffer appends we just did.
10065            return;
10066        }
10067
10068        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10069        // (After this point, we shouldn't access AMS internal data structures.)
10070        new Thread("Error dump: " + dropboxTag) {
10071            @Override
10072            public void run() {
10073                // 5 second sleep to let stacks arrive and be batched together
10074                try {
10075                    Thread.sleep(5000);  // 5 seconds
10076                } catch (InterruptedException e) {}
10077
10078                String errorReport;
10079                synchronized (mStrictModeBuffer) {
10080                    errorReport = mStrictModeBuffer.toString();
10081                    if (errorReport.length() == 0) {
10082                        return;
10083                    }
10084                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10085                    mStrictModeBuffer.trimToSize();
10086                }
10087                dbox.addText(dropboxTag, errorReport);
10088            }
10089        }.start();
10090    }
10091
10092    /**
10093     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10094     * @param app object of the crashing app, null for the system server
10095     * @param tag reported by the caller
10096     * @param crashInfo describing the context of the error
10097     * @return true if the process should exit immediately (WTF is fatal)
10098     */
10099    public boolean handleApplicationWtf(IBinder app, String tag,
10100            ApplicationErrorReport.CrashInfo crashInfo) {
10101        ProcessRecord r = findAppProcess(app, "WTF");
10102        final String processName = app == null ? "system_server"
10103                : (r == null ? "unknown" : r.processName);
10104
10105        EventLog.writeEvent(EventLogTags.AM_WTF,
10106                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10107                processName,
10108                r == null ? -1 : r.info.flags,
10109                tag, crashInfo.exceptionMessage);
10110
10111        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10112
10113        if (r != null && r.pid != Process.myPid() &&
10114                Settings.Global.getInt(mContext.getContentResolver(),
10115                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10116            crashApplication(r, crashInfo);
10117            return true;
10118        } else {
10119            return false;
10120        }
10121    }
10122
10123    /**
10124     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10125     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10126     */
10127    private ProcessRecord findAppProcess(IBinder app, String reason) {
10128        if (app == null) {
10129            return null;
10130        }
10131
10132        synchronized (this) {
10133            final int NP = mProcessNames.getMap().size();
10134            for (int ip=0; ip<NP; ip++) {
10135                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10136                final int NA = apps.size();
10137                for (int ia=0; ia<NA; ia++) {
10138                    ProcessRecord p = apps.valueAt(ia);
10139                    if (p.thread != null && p.thread.asBinder() == app) {
10140                        return p;
10141                    }
10142                }
10143            }
10144
10145            Slog.w(TAG, "Can't find mystery application for " + reason
10146                    + " from pid=" + Binder.getCallingPid()
10147                    + " uid=" + Binder.getCallingUid() + ": " + app);
10148            return null;
10149        }
10150    }
10151
10152    /**
10153     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10154     * to append various headers to the dropbox log text.
10155     */
10156    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10157            StringBuilder sb) {
10158        // Watchdog thread ends up invoking this function (with
10159        // a null ProcessRecord) to add the stack file to dropbox.
10160        // Do not acquire a lock on this (am) in such cases, as it
10161        // could cause a potential deadlock, if and when watchdog
10162        // is invoked due to unavailability of lock on am and it
10163        // would prevent watchdog from killing system_server.
10164        if (process == null) {
10165            sb.append("Process: ").append(processName).append("\n");
10166            return;
10167        }
10168        // Note: ProcessRecord 'process' is guarded by the service
10169        // instance.  (notably process.pkgList, which could otherwise change
10170        // concurrently during execution of this method)
10171        synchronized (this) {
10172            sb.append("Process: ").append(processName).append("\n");
10173            int flags = process.info.flags;
10174            IPackageManager pm = AppGlobals.getPackageManager();
10175            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10176            for (int ip=0; ip<process.pkgList.size(); ip++) {
10177                String pkg = process.pkgList.keyAt(ip);
10178                sb.append("Package: ").append(pkg);
10179                try {
10180                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10181                    if (pi != null) {
10182                        sb.append(" v").append(pi.versionCode);
10183                        if (pi.versionName != null) {
10184                            sb.append(" (").append(pi.versionName).append(")");
10185                        }
10186                    }
10187                } catch (RemoteException e) {
10188                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10189                }
10190                sb.append("\n");
10191            }
10192        }
10193    }
10194
10195    private static String processClass(ProcessRecord process) {
10196        if (process == null || process.pid == MY_PID) {
10197            return "system_server";
10198        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10199            return "system_app";
10200        } else {
10201            return "data_app";
10202        }
10203    }
10204
10205    /**
10206     * Write a description of an error (crash, WTF, ANR) to the drop box.
10207     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10208     * @param process which caused the error, null means the system server
10209     * @param activity which triggered the error, null if unknown
10210     * @param parent activity related to the error, null if unknown
10211     * @param subject line related to the error, null if absent
10212     * @param report in long form describing the error, null if absent
10213     * @param logFile to include in the report, null if none
10214     * @param crashInfo giving an application stack trace, null if absent
10215     */
10216    public void addErrorToDropBox(String eventType,
10217            ProcessRecord process, String processName, ActivityRecord activity,
10218            ActivityRecord parent, String subject,
10219            final String report, final File logFile,
10220            final ApplicationErrorReport.CrashInfo crashInfo) {
10221        // NOTE -- this must never acquire the ActivityManagerService lock,
10222        // otherwise the watchdog may be prevented from resetting the system.
10223
10224        final String dropboxTag = processClass(process) + "_" + eventType;
10225        final DropBoxManager dbox = (DropBoxManager)
10226                mContext.getSystemService(Context.DROPBOX_SERVICE);
10227
10228        // Exit early if the dropbox isn't configured to accept this report type.
10229        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10230
10231        final StringBuilder sb = new StringBuilder(1024);
10232        appendDropBoxProcessHeaders(process, processName, sb);
10233        if (activity != null) {
10234            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10235        }
10236        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10237            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10238        }
10239        if (parent != null && parent != activity) {
10240            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10241        }
10242        if (subject != null) {
10243            sb.append("Subject: ").append(subject).append("\n");
10244        }
10245        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10246        if (Debug.isDebuggerConnected()) {
10247            sb.append("Debugger: Connected\n");
10248        }
10249        sb.append("\n");
10250
10251        // Do the rest in a worker thread to avoid blocking the caller on I/O
10252        // (After this point, we shouldn't access AMS internal data structures.)
10253        Thread worker = new Thread("Error dump: " + dropboxTag) {
10254            @Override
10255            public void run() {
10256                if (report != null) {
10257                    sb.append(report);
10258                }
10259                if (logFile != null) {
10260                    try {
10261                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10262                                    "\n\n[[TRUNCATED]]"));
10263                    } catch (IOException e) {
10264                        Slog.e(TAG, "Error reading " + logFile, e);
10265                    }
10266                }
10267                if (crashInfo != null && crashInfo.stackTrace != null) {
10268                    sb.append(crashInfo.stackTrace);
10269                }
10270
10271                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10272                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10273                if (lines > 0) {
10274                    sb.append("\n");
10275
10276                    // Merge several logcat streams, and take the last N lines
10277                    InputStreamReader input = null;
10278                    try {
10279                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10280                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10281                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10282
10283                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10284                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10285                        input = new InputStreamReader(logcat.getInputStream());
10286
10287                        int num;
10288                        char[] buf = new char[8192];
10289                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10290                    } catch (IOException e) {
10291                        Slog.e(TAG, "Error running logcat", e);
10292                    } finally {
10293                        if (input != null) try { input.close(); } catch (IOException e) {}
10294                    }
10295                }
10296
10297                dbox.addText(dropboxTag, sb.toString());
10298            }
10299        };
10300
10301        if (process == null) {
10302            // If process is null, we are being called from some internal code
10303            // and may be about to die -- run this synchronously.
10304            worker.run();
10305        } else {
10306            worker.start();
10307        }
10308    }
10309
10310    /**
10311     * Bring up the "unexpected error" dialog box for a crashing app.
10312     * Deal with edge cases (intercepts from instrumented applications,
10313     * ActivityController, error intent receivers, that sort of thing).
10314     * @param r the application crashing
10315     * @param crashInfo describing the failure
10316     */
10317    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10318        long timeMillis = System.currentTimeMillis();
10319        String shortMsg = crashInfo.exceptionClassName;
10320        String longMsg = crashInfo.exceptionMessage;
10321        String stackTrace = crashInfo.stackTrace;
10322        if (shortMsg != null && longMsg != null) {
10323            longMsg = shortMsg + ": " + longMsg;
10324        } else if (shortMsg != null) {
10325            longMsg = shortMsg;
10326        }
10327
10328        AppErrorResult result = new AppErrorResult();
10329        synchronized (this) {
10330            if (mController != null) {
10331                try {
10332                    String name = r != null ? r.processName : null;
10333                    int pid = r != null ? r.pid : Binder.getCallingPid();
10334                    if (!mController.appCrashed(name, pid,
10335                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10336                        Slog.w(TAG, "Force-killing crashed app " + name
10337                                + " at watcher's request");
10338                        Process.killProcess(pid);
10339                        return;
10340                    }
10341                } catch (RemoteException e) {
10342                    mController = null;
10343                    Watchdog.getInstance().setActivityController(null);
10344                }
10345            }
10346
10347            final long origId = Binder.clearCallingIdentity();
10348
10349            // If this process is running instrumentation, finish it.
10350            if (r != null && r.instrumentationClass != null) {
10351                Slog.w(TAG, "Error in app " + r.processName
10352                      + " running instrumentation " + r.instrumentationClass + ":");
10353                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10354                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10355                Bundle info = new Bundle();
10356                info.putString("shortMsg", shortMsg);
10357                info.putString("longMsg", longMsg);
10358                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10359                Binder.restoreCallingIdentity(origId);
10360                return;
10361            }
10362
10363            // If we can't identify the process or it's already exceeded its crash quota,
10364            // quit right away without showing a crash dialog.
10365            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10366                Binder.restoreCallingIdentity(origId);
10367                return;
10368            }
10369
10370            Message msg = Message.obtain();
10371            msg.what = SHOW_ERROR_MSG;
10372            HashMap data = new HashMap();
10373            data.put("result", result);
10374            data.put("app", r);
10375            msg.obj = data;
10376            mHandler.sendMessage(msg);
10377
10378            Binder.restoreCallingIdentity(origId);
10379        }
10380
10381        int res = result.get();
10382
10383        Intent appErrorIntent = null;
10384        synchronized (this) {
10385            if (r != null && !r.isolated) {
10386                // XXX Can't keep track of crash time for isolated processes,
10387                // since they don't have a persistent identity.
10388                mProcessCrashTimes.put(r.info.processName, r.uid,
10389                        SystemClock.uptimeMillis());
10390            }
10391            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10392                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10393            }
10394        }
10395
10396        if (appErrorIntent != null) {
10397            try {
10398                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10399            } catch (ActivityNotFoundException e) {
10400                Slog.w(TAG, "bug report receiver dissappeared", e);
10401            }
10402        }
10403    }
10404
10405    Intent createAppErrorIntentLocked(ProcessRecord r,
10406            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10407        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10408        if (report == null) {
10409            return null;
10410        }
10411        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10412        result.setComponent(r.errorReportReceiver);
10413        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10414        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10415        return result;
10416    }
10417
10418    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10419            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10420        if (r.errorReportReceiver == null) {
10421            return null;
10422        }
10423
10424        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10425            return null;
10426        }
10427
10428        ApplicationErrorReport report = new ApplicationErrorReport();
10429        report.packageName = r.info.packageName;
10430        report.installerPackageName = r.errorReportReceiver.getPackageName();
10431        report.processName = r.processName;
10432        report.time = timeMillis;
10433        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10434
10435        if (r.crashing || r.forceCrashReport) {
10436            report.type = ApplicationErrorReport.TYPE_CRASH;
10437            report.crashInfo = crashInfo;
10438        } else if (r.notResponding) {
10439            report.type = ApplicationErrorReport.TYPE_ANR;
10440            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10441
10442            report.anrInfo.activity = r.notRespondingReport.tag;
10443            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10444            report.anrInfo.info = r.notRespondingReport.longMsg;
10445        }
10446
10447        return report;
10448    }
10449
10450    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10451        enforceNotIsolatedCaller("getProcessesInErrorState");
10452        // assume our apps are happy - lazy create the list
10453        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10454
10455        final boolean allUsers = ActivityManager.checkUidPermission(
10456                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10457                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10458        int userId = UserHandle.getUserId(Binder.getCallingUid());
10459
10460        synchronized (this) {
10461
10462            // iterate across all processes
10463            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10464                ProcessRecord app = mLruProcesses.get(i);
10465                if (!allUsers && app.userId != userId) {
10466                    continue;
10467                }
10468                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10469                    // This one's in trouble, so we'll generate a report for it
10470                    // crashes are higher priority (in case there's a crash *and* an anr)
10471                    ActivityManager.ProcessErrorStateInfo report = null;
10472                    if (app.crashing) {
10473                        report = app.crashingReport;
10474                    } else if (app.notResponding) {
10475                        report = app.notRespondingReport;
10476                    }
10477
10478                    if (report != null) {
10479                        if (errList == null) {
10480                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10481                        }
10482                        errList.add(report);
10483                    } else {
10484                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10485                                " crashing = " + app.crashing +
10486                                " notResponding = " + app.notResponding);
10487                    }
10488                }
10489            }
10490        }
10491
10492        return errList;
10493    }
10494
10495    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10496        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10497            if (currApp != null) {
10498                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10499            }
10500            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10501        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10502            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10503        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10504            if (currApp != null) {
10505                currApp.lru = 0;
10506            }
10507            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10508        } else if (adj >= ProcessList.SERVICE_ADJ) {
10509            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10510        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10511            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10512        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10514        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10516        } else {
10517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10518        }
10519    }
10520
10521    private void fillInProcMemInfo(ProcessRecord app,
10522            ActivityManager.RunningAppProcessInfo outInfo) {
10523        outInfo.pid = app.pid;
10524        outInfo.uid = app.info.uid;
10525        if (mHeavyWeightProcess == app) {
10526            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10527        }
10528        if (app.persistent) {
10529            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10530        }
10531        if (app.activities.size() > 0) {
10532            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10533        }
10534        outInfo.lastTrimLevel = app.trimMemoryLevel;
10535        int adj = app.curAdj;
10536        outInfo.importance = oomAdjToImportance(adj, outInfo);
10537        outInfo.importanceReasonCode = app.adjTypeCode;
10538        outInfo.processState = app.curProcState;
10539    }
10540
10541    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10542        enforceNotIsolatedCaller("getRunningAppProcesses");
10543        // Lazy instantiation of list
10544        List<ActivityManager.RunningAppProcessInfo> runList = null;
10545        final boolean allUsers = ActivityManager.checkUidPermission(
10546                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10547                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10548        int userId = UserHandle.getUserId(Binder.getCallingUid());
10549        synchronized (this) {
10550            // Iterate across all processes
10551            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10552                ProcessRecord app = mLruProcesses.get(i);
10553                if (!allUsers && app.userId != userId) {
10554                    continue;
10555                }
10556                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10557                    // Generate process state info for running application
10558                    ActivityManager.RunningAppProcessInfo currApp =
10559                        new ActivityManager.RunningAppProcessInfo(app.processName,
10560                                app.pid, app.getPackageList());
10561                    fillInProcMemInfo(app, currApp);
10562                    if (app.adjSource instanceof ProcessRecord) {
10563                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10564                        currApp.importanceReasonImportance = oomAdjToImportance(
10565                                app.adjSourceOom, null);
10566                    } else if (app.adjSource instanceof ActivityRecord) {
10567                        ActivityRecord r = (ActivityRecord)app.adjSource;
10568                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10569                    }
10570                    if (app.adjTarget instanceof ComponentName) {
10571                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10572                    }
10573                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10574                    //        + " lru=" + currApp.lru);
10575                    if (runList == null) {
10576                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10577                    }
10578                    runList.add(currApp);
10579                }
10580            }
10581        }
10582        return runList;
10583    }
10584
10585    public List<ApplicationInfo> getRunningExternalApplications() {
10586        enforceNotIsolatedCaller("getRunningExternalApplications");
10587        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10588        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10589        if (runningApps != null && runningApps.size() > 0) {
10590            Set<String> extList = new HashSet<String>();
10591            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10592                if (app.pkgList != null) {
10593                    for (String pkg : app.pkgList) {
10594                        extList.add(pkg);
10595                    }
10596                }
10597            }
10598            IPackageManager pm = AppGlobals.getPackageManager();
10599            for (String pkg : extList) {
10600                try {
10601                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10602                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10603                        retList.add(info);
10604                    }
10605                } catch (RemoteException e) {
10606                }
10607            }
10608        }
10609        return retList;
10610    }
10611
10612    @Override
10613    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10614        enforceNotIsolatedCaller("getMyMemoryState");
10615        synchronized (this) {
10616            ProcessRecord proc;
10617            synchronized (mPidsSelfLocked) {
10618                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10619            }
10620            fillInProcMemInfo(proc, outInfo);
10621        }
10622    }
10623
10624    @Override
10625    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10626        if (checkCallingPermission(android.Manifest.permission.DUMP)
10627                != PackageManager.PERMISSION_GRANTED) {
10628            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10629                    + Binder.getCallingPid()
10630                    + ", uid=" + Binder.getCallingUid()
10631                    + " without permission "
10632                    + android.Manifest.permission.DUMP);
10633            return;
10634        }
10635
10636        boolean dumpAll = false;
10637        boolean dumpClient = false;
10638        String dumpPackage = null;
10639
10640        int opti = 0;
10641        while (opti < args.length) {
10642            String opt = args[opti];
10643            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10644                break;
10645            }
10646            opti++;
10647            if ("-a".equals(opt)) {
10648                dumpAll = true;
10649            } else if ("-c".equals(opt)) {
10650                dumpClient = true;
10651            } else if ("-h".equals(opt)) {
10652                pw.println("Activity manager dump options:");
10653                pw.println("  [-a] [-c] [-h] [cmd] ...");
10654                pw.println("  cmd may be one of:");
10655                pw.println("    a[ctivities]: activity stack state");
10656                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10657                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10658                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10659                pw.println("    o[om]: out of memory management");
10660                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10661                pw.println("    provider [COMP_SPEC]: provider client-side state");
10662                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10663                pw.println("    service [COMP_SPEC]: service client-side state");
10664                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10665                pw.println("    all: dump all activities");
10666                pw.println("    top: dump the top activity");
10667                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10668                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10669                pw.println("    a partial substring in a component name, a");
10670                pw.println("    hex object identifier.");
10671                pw.println("  -a: include all available server state.");
10672                pw.println("  -c: include client state.");
10673                return;
10674            } else {
10675                pw.println("Unknown argument: " + opt + "; use -h for help");
10676            }
10677        }
10678
10679        long origId = Binder.clearCallingIdentity();
10680        boolean more = false;
10681        // Is the caller requesting to dump a particular piece of data?
10682        if (opti < args.length) {
10683            String cmd = args[opti];
10684            opti++;
10685            if ("activities".equals(cmd) || "a".equals(cmd)) {
10686                synchronized (this) {
10687                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10688                }
10689            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10690                String[] newArgs;
10691                String name;
10692                if (opti >= args.length) {
10693                    name = null;
10694                    newArgs = EMPTY_STRING_ARRAY;
10695                } else {
10696                    name = args[opti];
10697                    opti++;
10698                    newArgs = new String[args.length - opti];
10699                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10700                            args.length - opti);
10701                }
10702                synchronized (this) {
10703                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10704                }
10705            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10706                String[] newArgs;
10707                String name;
10708                if (opti >= args.length) {
10709                    name = null;
10710                    newArgs = EMPTY_STRING_ARRAY;
10711                } else {
10712                    name = args[opti];
10713                    opti++;
10714                    newArgs = new String[args.length - opti];
10715                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10716                            args.length - opti);
10717                }
10718                synchronized (this) {
10719                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10720                }
10721            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10722                String[] newArgs;
10723                String name;
10724                if (opti >= args.length) {
10725                    name = null;
10726                    newArgs = EMPTY_STRING_ARRAY;
10727                } else {
10728                    name = args[opti];
10729                    opti++;
10730                    newArgs = new String[args.length - opti];
10731                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10732                            args.length - opti);
10733                }
10734                synchronized (this) {
10735                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10736                }
10737            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10738                synchronized (this) {
10739                    dumpOomLocked(fd, pw, args, opti, true);
10740                }
10741            } else if ("provider".equals(cmd)) {
10742                String[] newArgs;
10743                String name;
10744                if (opti >= args.length) {
10745                    name = null;
10746                    newArgs = EMPTY_STRING_ARRAY;
10747                } else {
10748                    name = args[opti];
10749                    opti++;
10750                    newArgs = new String[args.length - opti];
10751                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10752                }
10753                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10754                    pw.println("No providers match: " + name);
10755                    pw.println("Use -h for help.");
10756                }
10757            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10758                synchronized (this) {
10759                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10760                }
10761            } else if ("service".equals(cmd)) {
10762                String[] newArgs;
10763                String name;
10764                if (opti >= args.length) {
10765                    name = null;
10766                    newArgs = EMPTY_STRING_ARRAY;
10767                } else {
10768                    name = args[opti];
10769                    opti++;
10770                    newArgs = new String[args.length - opti];
10771                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10772                            args.length - opti);
10773                }
10774                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10775                    pw.println("No services match: " + name);
10776                    pw.println("Use -h for help.");
10777                }
10778            } else if ("package".equals(cmd)) {
10779                String[] newArgs;
10780                if (opti >= args.length) {
10781                    pw.println("package: no package name specified");
10782                    pw.println("Use -h for help.");
10783                } else {
10784                    dumpPackage = args[opti];
10785                    opti++;
10786                    newArgs = new String[args.length - opti];
10787                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10788                            args.length - opti);
10789                    args = newArgs;
10790                    opti = 0;
10791                    more = true;
10792                }
10793            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10794                synchronized (this) {
10795                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10796                }
10797            } else {
10798                // Dumping a single activity?
10799                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10800                    pw.println("Bad activity command, or no activities match: " + cmd);
10801                    pw.println("Use -h for help.");
10802                }
10803            }
10804            if (!more) {
10805                Binder.restoreCallingIdentity(origId);
10806                return;
10807            }
10808        }
10809
10810        // No piece of data specified, dump everything.
10811        synchronized (this) {
10812            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10813            pw.println();
10814            if (dumpAll) {
10815                pw.println("-------------------------------------------------------------------------------");
10816            }
10817            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10818            pw.println();
10819            if (dumpAll) {
10820                pw.println("-------------------------------------------------------------------------------");
10821            }
10822            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10823            pw.println();
10824            if (dumpAll) {
10825                pw.println("-------------------------------------------------------------------------------");
10826            }
10827            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10828            pw.println();
10829            if (dumpAll) {
10830                pw.println("-------------------------------------------------------------------------------");
10831            }
10832            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10833            pw.println();
10834            if (dumpAll) {
10835                pw.println("-------------------------------------------------------------------------------");
10836            }
10837            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10838        }
10839        Binder.restoreCallingIdentity(origId);
10840    }
10841
10842    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10843            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10844        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10845
10846        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10847                dumpPackage);
10848        boolean needSep = printedAnything;
10849
10850        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10851                dumpPackage, needSep, "  mFocusedActivity: ");
10852        if (printed) {
10853            printedAnything = true;
10854            needSep = false;
10855        }
10856
10857        if (dumpPackage == null) {
10858            if (needSep) {
10859                pw.println();
10860            }
10861            needSep = true;
10862            printedAnything = true;
10863            mStackSupervisor.dump(pw, "  ");
10864        }
10865
10866        if (mRecentTasks.size() > 0) {
10867            boolean printedHeader = false;
10868
10869            final int N = mRecentTasks.size();
10870            for (int i=0; i<N; i++) {
10871                TaskRecord tr = mRecentTasks.get(i);
10872                if (dumpPackage != null) {
10873                    if (tr.realActivity == null ||
10874                            !dumpPackage.equals(tr.realActivity)) {
10875                        continue;
10876                    }
10877                }
10878                if (!printedHeader) {
10879                    if (needSep) {
10880                        pw.println();
10881                    }
10882                    pw.println("  Recent tasks:");
10883                    printedHeader = true;
10884                    printedAnything = true;
10885                }
10886                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10887                        pw.println(tr);
10888                if (dumpAll) {
10889                    mRecentTasks.get(i).dump(pw, "    ");
10890                }
10891            }
10892        }
10893
10894        if (!printedAnything) {
10895            pw.println("  (nothing)");
10896        }
10897    }
10898
10899    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10900            int opti, boolean dumpAll, String dumpPackage) {
10901        boolean needSep = false;
10902        boolean printedAnything = false;
10903        int numPers = 0;
10904
10905        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10906
10907        if (dumpAll) {
10908            final int NP = mProcessNames.getMap().size();
10909            for (int ip=0; ip<NP; ip++) {
10910                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10911                final int NA = procs.size();
10912                for (int ia=0; ia<NA; ia++) {
10913                    ProcessRecord r = procs.valueAt(ia);
10914                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10915                        continue;
10916                    }
10917                    if (!needSep) {
10918                        pw.println("  All known processes:");
10919                        needSep = true;
10920                        printedAnything = true;
10921                    }
10922                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10923                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10924                        pw.print(" "); pw.println(r);
10925                    r.dump(pw, "    ");
10926                    if (r.persistent) {
10927                        numPers++;
10928                    }
10929                }
10930            }
10931        }
10932
10933        if (mIsolatedProcesses.size() > 0) {
10934            boolean printed = false;
10935            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10936                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10937                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10938                    continue;
10939                }
10940                if (!printed) {
10941                    if (needSep) {
10942                        pw.println();
10943                    }
10944                    pw.println("  Isolated process list (sorted by uid):");
10945                    printedAnything = true;
10946                    printed = true;
10947                    needSep = true;
10948                }
10949                pw.println(String.format("%sIsolated #%2d: %s",
10950                        "    ", i, r.toString()));
10951            }
10952        }
10953
10954        if (mLruProcesses.size() > 0) {
10955            if (needSep) {
10956                pw.println();
10957            }
10958            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10959                    pw.print(" total, non-act at ");
10960                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10961                    pw.print(", non-svc at ");
10962                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10963                    pw.println("):");
10964            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10965            needSep = true;
10966            printedAnything = true;
10967        }
10968
10969        if (dumpAll || dumpPackage != null) {
10970            synchronized (mPidsSelfLocked) {
10971                boolean printed = false;
10972                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10973                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10974                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10975                        continue;
10976                    }
10977                    if (!printed) {
10978                        if (needSep) pw.println();
10979                        needSep = true;
10980                        pw.println("  PID mappings:");
10981                        printed = true;
10982                        printedAnything = true;
10983                    }
10984                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10985                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10986                }
10987            }
10988        }
10989
10990        if (mForegroundProcesses.size() > 0) {
10991            synchronized (mPidsSelfLocked) {
10992                boolean printed = false;
10993                for (int i=0; i<mForegroundProcesses.size(); i++) {
10994                    ProcessRecord r = mPidsSelfLocked.get(
10995                            mForegroundProcesses.valueAt(i).pid);
10996                    if (dumpPackage != null && (r == null
10997                            || !r.pkgList.containsKey(dumpPackage))) {
10998                        continue;
10999                    }
11000                    if (!printed) {
11001                        if (needSep) pw.println();
11002                        needSep = true;
11003                        pw.println("  Foreground Processes:");
11004                        printed = true;
11005                        printedAnything = true;
11006                    }
11007                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11008                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11009                }
11010            }
11011        }
11012
11013        if (mPersistentStartingProcesses.size() > 0) {
11014            if (needSep) pw.println();
11015            needSep = true;
11016            printedAnything = true;
11017            pw.println("  Persisent processes that are starting:");
11018            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11019                    "Starting Norm", "Restarting PERS", dumpPackage);
11020        }
11021
11022        if (mRemovedProcesses.size() > 0) {
11023            if (needSep) pw.println();
11024            needSep = true;
11025            printedAnything = true;
11026            pw.println("  Processes that are being removed:");
11027            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11028                    "Removed Norm", "Removed PERS", dumpPackage);
11029        }
11030
11031        if (mProcessesOnHold.size() > 0) {
11032            if (needSep) pw.println();
11033            needSep = true;
11034            printedAnything = true;
11035            pw.println("  Processes that are on old until the system is ready:");
11036            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11037                    "OnHold Norm", "OnHold PERS", dumpPackage);
11038        }
11039
11040        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11041
11042        if (mProcessCrashTimes.getMap().size() > 0) {
11043            boolean printed = false;
11044            long now = SystemClock.uptimeMillis();
11045            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11046            final int NP = pmap.size();
11047            for (int ip=0; ip<NP; ip++) {
11048                String pname = pmap.keyAt(ip);
11049                SparseArray<Long> uids = pmap.valueAt(ip);
11050                final int N = uids.size();
11051                for (int i=0; i<N; i++) {
11052                    int puid = uids.keyAt(i);
11053                    ProcessRecord r = mProcessNames.get(pname, puid);
11054                    if (dumpPackage != null && (r == null
11055                            || !r.pkgList.containsKey(dumpPackage))) {
11056                        continue;
11057                    }
11058                    if (!printed) {
11059                        if (needSep) pw.println();
11060                        needSep = true;
11061                        pw.println("  Time since processes crashed:");
11062                        printed = true;
11063                        printedAnything = true;
11064                    }
11065                    pw.print("    Process "); pw.print(pname);
11066                            pw.print(" uid "); pw.print(puid);
11067                            pw.print(": last crashed ");
11068                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11069                            pw.println(" ago");
11070                }
11071            }
11072        }
11073
11074        if (mBadProcesses.getMap().size() > 0) {
11075            boolean printed = false;
11076            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11077            final int NP = pmap.size();
11078            for (int ip=0; ip<NP; ip++) {
11079                String pname = pmap.keyAt(ip);
11080                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11081                final int N = uids.size();
11082                for (int i=0; i<N; i++) {
11083                    int puid = uids.keyAt(i);
11084                    ProcessRecord r = mProcessNames.get(pname, puid);
11085                    if (dumpPackage != null && (r == null
11086                            || !r.pkgList.containsKey(dumpPackage))) {
11087                        continue;
11088                    }
11089                    if (!printed) {
11090                        if (needSep) pw.println();
11091                        needSep = true;
11092                        pw.println("  Bad processes:");
11093                        printedAnything = true;
11094                    }
11095                    BadProcessInfo info = uids.valueAt(i);
11096                    pw.print("    Bad process "); pw.print(pname);
11097                            pw.print(" uid "); pw.print(puid);
11098                            pw.print(": crashed at time "); pw.println(info.time);
11099                    if (info.shortMsg != null) {
11100                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11101                    }
11102                    if (info.longMsg != null) {
11103                        pw.print("      Long msg: "); pw.println(info.longMsg);
11104                    }
11105                    if (info.stack != null) {
11106                        pw.println("      Stack:");
11107                        int lastPos = 0;
11108                        for (int pos=0; pos<info.stack.length(); pos++) {
11109                            if (info.stack.charAt(pos) == '\n') {
11110                                pw.print("        ");
11111                                pw.write(info.stack, lastPos, pos-lastPos);
11112                                pw.println();
11113                                lastPos = pos+1;
11114                            }
11115                        }
11116                        if (lastPos < info.stack.length()) {
11117                            pw.print("        ");
11118                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11119                            pw.println();
11120                        }
11121                    }
11122                }
11123            }
11124        }
11125
11126        if (dumpPackage == null) {
11127            pw.println();
11128            needSep = false;
11129            pw.println("  mStartedUsers:");
11130            for (int i=0; i<mStartedUsers.size(); i++) {
11131                UserStartedState uss = mStartedUsers.valueAt(i);
11132                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11133                        pw.print(": "); uss.dump("", pw);
11134            }
11135            pw.print("  mStartedUserArray: [");
11136            for (int i=0; i<mStartedUserArray.length; i++) {
11137                if (i > 0) pw.print(", ");
11138                pw.print(mStartedUserArray[i]);
11139            }
11140            pw.println("]");
11141            pw.print("  mUserLru: [");
11142            for (int i=0; i<mUserLru.size(); i++) {
11143                if (i > 0) pw.print(", ");
11144                pw.print(mUserLru.get(i));
11145            }
11146            pw.println("]");
11147            if (dumpAll) {
11148                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11149            }
11150        }
11151        if (mHomeProcess != null && (dumpPackage == null
11152                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11153            if (needSep) {
11154                pw.println();
11155                needSep = false;
11156            }
11157            pw.println("  mHomeProcess: " + mHomeProcess);
11158        }
11159        if (mPreviousProcess != null && (dumpPackage == null
11160                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11161            if (needSep) {
11162                pw.println();
11163                needSep = false;
11164            }
11165            pw.println("  mPreviousProcess: " + mPreviousProcess);
11166        }
11167        if (dumpAll) {
11168            StringBuilder sb = new StringBuilder(128);
11169            sb.append("  mPreviousProcessVisibleTime: ");
11170            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11171            pw.println(sb);
11172        }
11173        if (mHeavyWeightProcess != null && (dumpPackage == null
11174                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11175            if (needSep) {
11176                pw.println();
11177                needSep = false;
11178            }
11179            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11180        }
11181        if (dumpPackage == null) {
11182            pw.println("  mConfiguration: " + mConfiguration);
11183        }
11184        if (dumpAll) {
11185            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11186            if (mCompatModePackages.getPackages().size() > 0) {
11187                boolean printed = false;
11188                for (Map.Entry<String, Integer> entry
11189                        : mCompatModePackages.getPackages().entrySet()) {
11190                    String pkg = entry.getKey();
11191                    int mode = entry.getValue();
11192                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11193                        continue;
11194                    }
11195                    if (!printed) {
11196                        pw.println("  mScreenCompatPackages:");
11197                        printed = true;
11198                    }
11199                    pw.print("    "); pw.print(pkg); pw.print(": ");
11200                            pw.print(mode); pw.println();
11201                }
11202            }
11203        }
11204        if (dumpPackage == null) {
11205            if (mSleeping || mWentToSleep || mLockScreenShown) {
11206                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11207                        + " mLockScreenShown " + mLockScreenShown);
11208            }
11209            if (mShuttingDown || mRunningVoice) {
11210                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11211            }
11212        }
11213        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11214                || mOrigWaitForDebugger) {
11215            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11216                    || dumpPackage.equals(mOrigDebugApp)) {
11217                if (needSep) {
11218                    pw.println();
11219                    needSep = false;
11220                }
11221                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11222                        + " mDebugTransient=" + mDebugTransient
11223                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11224            }
11225        }
11226        if (mOpenGlTraceApp != null) {
11227            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11228                if (needSep) {
11229                    pw.println();
11230                    needSep = false;
11231                }
11232                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11233            }
11234        }
11235        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11236                || mProfileFd != null) {
11237            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11238                if (needSep) {
11239                    pw.println();
11240                    needSep = false;
11241                }
11242                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11243                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11244                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11245                        + mAutoStopProfiler);
11246            }
11247        }
11248        if (dumpPackage == null) {
11249            if (mAlwaysFinishActivities || mController != null) {
11250                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11251                        + " mController=" + mController);
11252            }
11253            if (dumpAll) {
11254                pw.println("  Total persistent processes: " + numPers);
11255                pw.println("  mProcessesReady=" + mProcessesReady
11256                        + " mSystemReady=" + mSystemReady);
11257                pw.println("  mBooting=" + mBooting
11258                        + " mBooted=" + mBooted
11259                        + " mFactoryTest=" + mFactoryTest);
11260                pw.print("  mLastPowerCheckRealtime=");
11261                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11262                        pw.println("");
11263                pw.print("  mLastPowerCheckUptime=");
11264                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11265                        pw.println("");
11266                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11267                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11268                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11269                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11270                        + " (" + mLruProcesses.size() + " total)"
11271                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11272                        + " mNumServiceProcs=" + mNumServiceProcs
11273                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11274                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11275                        + " mLastMemoryLevel" + mLastMemoryLevel
11276                        + " mLastNumProcesses" + mLastNumProcesses);
11277                long now = SystemClock.uptimeMillis();
11278                pw.print("  mLastIdleTime=");
11279                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11280                        pw.print(" mLowRamSinceLastIdle=");
11281                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11282                        pw.println();
11283            }
11284        }
11285
11286        if (!printedAnything) {
11287            pw.println("  (nothing)");
11288        }
11289    }
11290
11291    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11292            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11293        if (mProcessesToGc.size() > 0) {
11294            boolean printed = false;
11295            long now = SystemClock.uptimeMillis();
11296            for (int i=0; i<mProcessesToGc.size(); i++) {
11297                ProcessRecord proc = mProcessesToGc.get(i);
11298                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11299                    continue;
11300                }
11301                if (!printed) {
11302                    if (needSep) pw.println();
11303                    needSep = true;
11304                    pw.println("  Processes that are waiting to GC:");
11305                    printed = true;
11306                }
11307                pw.print("    Process "); pw.println(proc);
11308                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11309                        pw.print(", last gced=");
11310                        pw.print(now-proc.lastRequestedGc);
11311                        pw.print(" ms ago, last lowMem=");
11312                        pw.print(now-proc.lastLowMemory);
11313                        pw.println(" ms ago");
11314
11315            }
11316        }
11317        return needSep;
11318    }
11319
11320    void printOomLevel(PrintWriter pw, String name, int adj) {
11321        pw.print("    ");
11322        if (adj >= 0) {
11323            pw.print(' ');
11324            if (adj < 10) pw.print(' ');
11325        } else {
11326            if (adj > -10) pw.print(' ');
11327        }
11328        pw.print(adj);
11329        pw.print(": ");
11330        pw.print(name);
11331        pw.print(" (");
11332        pw.print(mProcessList.getMemLevel(adj)/1024);
11333        pw.println(" kB)");
11334    }
11335
11336    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11337            int opti, boolean dumpAll) {
11338        boolean needSep = false;
11339
11340        if (mLruProcesses.size() > 0) {
11341            if (needSep) pw.println();
11342            needSep = true;
11343            pw.println("  OOM levels:");
11344            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11345            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11346            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11347            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11348            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11349            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11350            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11351            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11352            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11353            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11354            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11355            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11356            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11357
11358            if (needSep) pw.println();
11359            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11360                    pw.print(" total, non-act at ");
11361                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11362                    pw.print(", non-svc at ");
11363                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11364                    pw.println("):");
11365            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11366            needSep = true;
11367        }
11368
11369        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11370
11371        pw.println();
11372        pw.println("  mHomeProcess: " + mHomeProcess);
11373        pw.println("  mPreviousProcess: " + mPreviousProcess);
11374        if (mHeavyWeightProcess != null) {
11375            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11376        }
11377
11378        return true;
11379    }
11380
11381    /**
11382     * There are three ways to call this:
11383     *  - no provider specified: dump all the providers
11384     *  - a flattened component name that matched an existing provider was specified as the
11385     *    first arg: dump that one provider
11386     *  - the first arg isn't the flattened component name of an existing provider:
11387     *    dump all providers whose component contains the first arg as a substring
11388     */
11389    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11390            int opti, boolean dumpAll) {
11391        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11392    }
11393
11394    static class ItemMatcher {
11395        ArrayList<ComponentName> components;
11396        ArrayList<String> strings;
11397        ArrayList<Integer> objects;
11398        boolean all;
11399
11400        ItemMatcher() {
11401            all = true;
11402        }
11403
11404        void build(String name) {
11405            ComponentName componentName = ComponentName.unflattenFromString(name);
11406            if (componentName != null) {
11407                if (components == null) {
11408                    components = new ArrayList<ComponentName>();
11409                }
11410                components.add(componentName);
11411                all = false;
11412            } else {
11413                int objectId = 0;
11414                // Not a '/' separated full component name; maybe an object ID?
11415                try {
11416                    objectId = Integer.parseInt(name, 16);
11417                    if (objects == null) {
11418                        objects = new ArrayList<Integer>();
11419                    }
11420                    objects.add(objectId);
11421                    all = false;
11422                } catch (RuntimeException e) {
11423                    // Not an integer; just do string match.
11424                    if (strings == null) {
11425                        strings = new ArrayList<String>();
11426                    }
11427                    strings.add(name);
11428                    all = false;
11429                }
11430            }
11431        }
11432
11433        int build(String[] args, int opti) {
11434            for (; opti<args.length; opti++) {
11435                String name = args[opti];
11436                if ("--".equals(name)) {
11437                    return opti+1;
11438                }
11439                build(name);
11440            }
11441            return opti;
11442        }
11443
11444        boolean match(Object object, ComponentName comp) {
11445            if (all) {
11446                return true;
11447            }
11448            if (components != null) {
11449                for (int i=0; i<components.size(); i++) {
11450                    if (components.get(i).equals(comp)) {
11451                        return true;
11452                    }
11453                }
11454            }
11455            if (objects != null) {
11456                for (int i=0; i<objects.size(); i++) {
11457                    if (System.identityHashCode(object) == objects.get(i)) {
11458                        return true;
11459                    }
11460                }
11461            }
11462            if (strings != null) {
11463                String flat = comp.flattenToString();
11464                for (int i=0; i<strings.size(); i++) {
11465                    if (flat.contains(strings.get(i))) {
11466                        return true;
11467                    }
11468                }
11469            }
11470            return false;
11471        }
11472    }
11473
11474    /**
11475     * There are three things that cmd can be:
11476     *  - a flattened component name that matches an existing activity
11477     *  - the cmd arg isn't the flattened component name of an existing activity:
11478     *    dump all activity whose component contains the cmd as a substring
11479     *  - A hex number of the ActivityRecord object instance.
11480     */
11481    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11482            int opti, boolean dumpAll) {
11483        ArrayList<ActivityRecord> activities;
11484
11485        synchronized (this) {
11486            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11487        }
11488
11489        if (activities.size() <= 0) {
11490            return false;
11491        }
11492
11493        String[] newArgs = new String[args.length - opti];
11494        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11495
11496        TaskRecord lastTask = null;
11497        boolean needSep = false;
11498        for (int i=activities.size()-1; i>=0; i--) {
11499            ActivityRecord r = activities.get(i);
11500            if (needSep) {
11501                pw.println();
11502            }
11503            needSep = true;
11504            synchronized (this) {
11505                if (lastTask != r.task) {
11506                    lastTask = r.task;
11507                    pw.print("TASK "); pw.print(lastTask.affinity);
11508                            pw.print(" id="); pw.println(lastTask.taskId);
11509                    if (dumpAll) {
11510                        lastTask.dump(pw, "  ");
11511                    }
11512                }
11513            }
11514            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11515        }
11516        return true;
11517    }
11518
11519    /**
11520     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11521     * there is a thread associated with the activity.
11522     */
11523    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11524            final ActivityRecord r, String[] args, boolean dumpAll) {
11525        String innerPrefix = prefix + "  ";
11526        synchronized (this) {
11527            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11528                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11529                    pw.print(" pid=");
11530                    if (r.app != null) pw.println(r.app.pid);
11531                    else pw.println("(not running)");
11532            if (dumpAll) {
11533                r.dump(pw, innerPrefix);
11534            }
11535        }
11536        if (r.app != null && r.app.thread != null) {
11537            // flush anything that is already in the PrintWriter since the thread is going
11538            // to write to the file descriptor directly
11539            pw.flush();
11540            try {
11541                TransferPipe tp = new TransferPipe();
11542                try {
11543                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11544                            r.appToken, innerPrefix, args);
11545                    tp.go(fd);
11546                } finally {
11547                    tp.kill();
11548                }
11549            } catch (IOException e) {
11550                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11551            } catch (RemoteException e) {
11552                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11553            }
11554        }
11555    }
11556
11557    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11558            int opti, boolean dumpAll, String dumpPackage) {
11559        boolean needSep = false;
11560        boolean onlyHistory = false;
11561        boolean printedAnything = false;
11562
11563        if ("history".equals(dumpPackage)) {
11564            if (opti < args.length && "-s".equals(args[opti])) {
11565                dumpAll = false;
11566            }
11567            onlyHistory = true;
11568            dumpPackage = null;
11569        }
11570
11571        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11572        if (!onlyHistory && dumpAll) {
11573            if (mRegisteredReceivers.size() > 0) {
11574                boolean printed = false;
11575                Iterator it = mRegisteredReceivers.values().iterator();
11576                while (it.hasNext()) {
11577                    ReceiverList r = (ReceiverList)it.next();
11578                    if (dumpPackage != null && (r.app == null ||
11579                            !dumpPackage.equals(r.app.info.packageName))) {
11580                        continue;
11581                    }
11582                    if (!printed) {
11583                        pw.println("  Registered Receivers:");
11584                        needSep = true;
11585                        printed = true;
11586                        printedAnything = true;
11587                    }
11588                    pw.print("  * "); pw.println(r);
11589                    r.dump(pw, "    ");
11590                }
11591            }
11592
11593            if (mReceiverResolver.dump(pw, needSep ?
11594                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11595                    "    ", dumpPackage, false)) {
11596                needSep = true;
11597                printedAnything = true;
11598            }
11599        }
11600
11601        for (BroadcastQueue q : mBroadcastQueues) {
11602            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11603            printedAnything |= needSep;
11604        }
11605
11606        needSep = true;
11607
11608        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11609            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11610                if (needSep) {
11611                    pw.println();
11612                }
11613                needSep = true;
11614                printedAnything = true;
11615                pw.print("  Sticky broadcasts for user ");
11616                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11617                StringBuilder sb = new StringBuilder(128);
11618                for (Map.Entry<String, ArrayList<Intent>> ent
11619                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11620                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11621                    if (dumpAll) {
11622                        pw.println(":");
11623                        ArrayList<Intent> intents = ent.getValue();
11624                        final int N = intents.size();
11625                        for (int i=0; i<N; i++) {
11626                            sb.setLength(0);
11627                            sb.append("    Intent: ");
11628                            intents.get(i).toShortString(sb, false, true, false, false);
11629                            pw.println(sb.toString());
11630                            Bundle bundle = intents.get(i).getExtras();
11631                            if (bundle != null) {
11632                                pw.print("      ");
11633                                pw.println(bundle.toString());
11634                            }
11635                        }
11636                    } else {
11637                        pw.println("");
11638                    }
11639                }
11640            }
11641        }
11642
11643        if (!onlyHistory && dumpAll) {
11644            pw.println();
11645            for (BroadcastQueue queue : mBroadcastQueues) {
11646                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11647                        + queue.mBroadcastsScheduled);
11648            }
11649            pw.println("  mHandler:");
11650            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11651            needSep = true;
11652            printedAnything = true;
11653        }
11654
11655        if (!printedAnything) {
11656            pw.println("  (nothing)");
11657        }
11658    }
11659
11660    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11661            int opti, boolean dumpAll, String dumpPackage) {
11662        boolean needSep;
11663        boolean printedAnything = false;
11664
11665        ItemMatcher matcher = new ItemMatcher();
11666        matcher.build(args, opti);
11667
11668        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11669
11670        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11671        printedAnything |= needSep;
11672
11673        if (mLaunchingProviders.size() > 0) {
11674            boolean printed = false;
11675            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11676                ContentProviderRecord r = mLaunchingProviders.get(i);
11677                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11678                    continue;
11679                }
11680                if (!printed) {
11681                    if (needSep) pw.println();
11682                    needSep = true;
11683                    pw.println("  Launching content providers:");
11684                    printed = true;
11685                    printedAnything = true;
11686                }
11687                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11688                        pw.println(r);
11689            }
11690        }
11691
11692        if (mGrantedUriPermissions.size() > 0) {
11693            boolean printed = false;
11694            int dumpUid = -2;
11695            if (dumpPackage != null) {
11696                try {
11697                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11698                } catch (NameNotFoundException e) {
11699                    dumpUid = -1;
11700                }
11701            }
11702            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11703                int uid = mGrantedUriPermissions.keyAt(i);
11704                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11705                    continue;
11706                }
11707                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11708                if (!printed) {
11709                    if (needSep) pw.println();
11710                    needSep = true;
11711                    pw.println("  Granted Uri Permissions:");
11712                    printed = true;
11713                    printedAnything = true;
11714                }
11715                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11716                for (UriPermission perm : perms.values()) {
11717                    pw.print("    "); pw.println(perm);
11718                    if (dumpAll) {
11719                        perm.dump(pw, "      ");
11720                    }
11721                }
11722            }
11723        }
11724
11725        if (!printedAnything) {
11726            pw.println("  (nothing)");
11727        }
11728    }
11729
11730    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11731            int opti, boolean dumpAll, String dumpPackage) {
11732        boolean printed = false;
11733
11734        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11735
11736        if (mIntentSenderRecords.size() > 0) {
11737            Iterator<WeakReference<PendingIntentRecord>> it
11738                    = mIntentSenderRecords.values().iterator();
11739            while (it.hasNext()) {
11740                WeakReference<PendingIntentRecord> ref = it.next();
11741                PendingIntentRecord rec = ref != null ? ref.get(): null;
11742                if (dumpPackage != null && (rec == null
11743                        || !dumpPackage.equals(rec.key.packageName))) {
11744                    continue;
11745                }
11746                printed = true;
11747                if (rec != null) {
11748                    pw.print("  * "); pw.println(rec);
11749                    if (dumpAll) {
11750                        rec.dump(pw, "    ");
11751                    }
11752                } else {
11753                    pw.print("  * "); pw.println(ref);
11754                }
11755            }
11756        }
11757
11758        if (!printed) {
11759            pw.println("  (nothing)");
11760        }
11761    }
11762
11763    private static final int dumpProcessList(PrintWriter pw,
11764            ActivityManagerService service, List list,
11765            String prefix, String normalLabel, String persistentLabel,
11766            String dumpPackage) {
11767        int numPers = 0;
11768        final int N = list.size()-1;
11769        for (int i=N; i>=0; i--) {
11770            ProcessRecord r = (ProcessRecord)list.get(i);
11771            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11772                continue;
11773            }
11774            pw.println(String.format("%s%s #%2d: %s",
11775                    prefix, (r.persistent ? persistentLabel : normalLabel),
11776                    i, r.toString()));
11777            if (r.persistent) {
11778                numPers++;
11779            }
11780        }
11781        return numPers;
11782    }
11783
11784    private static final boolean dumpProcessOomList(PrintWriter pw,
11785            ActivityManagerService service, List<ProcessRecord> origList,
11786            String prefix, String normalLabel, String persistentLabel,
11787            boolean inclDetails, String dumpPackage) {
11788
11789        ArrayList<Pair<ProcessRecord, Integer>> list
11790                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11791        for (int i=0; i<origList.size(); i++) {
11792            ProcessRecord r = origList.get(i);
11793            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11794                continue;
11795            }
11796            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11797        }
11798
11799        if (list.size() <= 0) {
11800            return false;
11801        }
11802
11803        Comparator<Pair<ProcessRecord, Integer>> comparator
11804                = new Comparator<Pair<ProcessRecord, Integer>>() {
11805            @Override
11806            public int compare(Pair<ProcessRecord, Integer> object1,
11807                    Pair<ProcessRecord, Integer> object2) {
11808                if (object1.first.setAdj != object2.first.setAdj) {
11809                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11810                }
11811                if (object1.second.intValue() != object2.second.intValue()) {
11812                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11813                }
11814                return 0;
11815            }
11816        };
11817
11818        Collections.sort(list, comparator);
11819
11820        final long curRealtime = SystemClock.elapsedRealtime();
11821        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11822        final long curUptime = SystemClock.uptimeMillis();
11823        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11824
11825        for (int i=list.size()-1; i>=0; i--) {
11826            ProcessRecord r = list.get(i).first;
11827            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11828            char schedGroup;
11829            switch (r.setSchedGroup) {
11830                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11831                    schedGroup = 'B';
11832                    break;
11833                case Process.THREAD_GROUP_DEFAULT:
11834                    schedGroup = 'F';
11835                    break;
11836                default:
11837                    schedGroup = '?';
11838                    break;
11839            }
11840            char foreground;
11841            if (r.foregroundActivities) {
11842                foreground = 'A';
11843            } else if (r.foregroundServices) {
11844                foreground = 'S';
11845            } else {
11846                foreground = ' ';
11847            }
11848            String procState = ProcessList.makeProcStateString(r.curProcState);
11849            pw.print(prefix);
11850            pw.print(r.persistent ? persistentLabel : normalLabel);
11851            pw.print(" #");
11852            int num = (origList.size()-1)-list.get(i).second;
11853            if (num < 10) pw.print(' ');
11854            pw.print(num);
11855            pw.print(": ");
11856            pw.print(oomAdj);
11857            pw.print(' ');
11858            pw.print(schedGroup);
11859            pw.print('/');
11860            pw.print(foreground);
11861            pw.print('/');
11862            pw.print(procState);
11863            pw.print(" trm:");
11864            if (r.trimMemoryLevel < 10) pw.print(' ');
11865            pw.print(r.trimMemoryLevel);
11866            pw.print(' ');
11867            pw.print(r.toShortString());
11868            pw.print(" (");
11869            pw.print(r.adjType);
11870            pw.println(')');
11871            if (r.adjSource != null || r.adjTarget != null) {
11872                pw.print(prefix);
11873                pw.print("    ");
11874                if (r.adjTarget instanceof ComponentName) {
11875                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11876                } else if (r.adjTarget != null) {
11877                    pw.print(r.adjTarget.toString());
11878                } else {
11879                    pw.print("{null}");
11880                }
11881                pw.print("<=");
11882                if (r.adjSource instanceof ProcessRecord) {
11883                    pw.print("Proc{");
11884                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11885                    pw.println("}");
11886                } else if (r.adjSource != null) {
11887                    pw.println(r.adjSource.toString());
11888                } else {
11889                    pw.println("{null}");
11890                }
11891            }
11892            if (inclDetails) {
11893                pw.print(prefix);
11894                pw.print("    ");
11895                pw.print("oom: max="); pw.print(r.maxAdj);
11896                pw.print(" curRaw="); pw.print(r.curRawAdj);
11897                pw.print(" setRaw="); pw.print(r.setRawAdj);
11898                pw.print(" cur="); pw.print(r.curAdj);
11899                pw.print(" set="); pw.println(r.setAdj);
11900                pw.print(prefix);
11901                pw.print("    ");
11902                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11903                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11904                pw.print(" lastPss="); pw.print(r.lastPss);
11905                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11906                pw.print(prefix);
11907                pw.print("    ");
11908                pw.print("keeping="); pw.print(r.keeping);
11909                pw.print(" cached="); pw.print(r.cached);
11910                pw.print(" empty="); pw.print(r.empty);
11911                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11912
11913                if (!r.keeping) {
11914                    if (r.lastWakeTime != 0) {
11915                        long wtime;
11916                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11917                        synchronized (stats) {
11918                            wtime = stats.getProcessWakeTime(r.info.uid,
11919                                    r.pid, curRealtime);
11920                        }
11921                        long timeUsed = wtime - r.lastWakeTime;
11922                        pw.print(prefix);
11923                        pw.print("    ");
11924                        pw.print("keep awake over ");
11925                        TimeUtils.formatDuration(realtimeSince, pw);
11926                        pw.print(" used ");
11927                        TimeUtils.formatDuration(timeUsed, pw);
11928                        pw.print(" (");
11929                        pw.print((timeUsed*100)/realtimeSince);
11930                        pw.println("%)");
11931                    }
11932                    if (r.lastCpuTime != 0) {
11933                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11934                        pw.print(prefix);
11935                        pw.print("    ");
11936                        pw.print("run cpu over ");
11937                        TimeUtils.formatDuration(uptimeSince, pw);
11938                        pw.print(" used ");
11939                        TimeUtils.formatDuration(timeUsed, pw);
11940                        pw.print(" (");
11941                        pw.print((timeUsed*100)/uptimeSince);
11942                        pw.println("%)");
11943                    }
11944                }
11945            }
11946        }
11947        return true;
11948    }
11949
11950    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11951        ArrayList<ProcessRecord> procs;
11952        synchronized (this) {
11953            if (args != null && args.length > start
11954                    && args[start].charAt(0) != '-') {
11955                procs = new ArrayList<ProcessRecord>();
11956                int pid = -1;
11957                try {
11958                    pid = Integer.parseInt(args[start]);
11959                } catch (NumberFormatException e) {
11960                }
11961                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11962                    ProcessRecord proc = mLruProcesses.get(i);
11963                    if (proc.pid == pid) {
11964                        procs.add(proc);
11965                    } else if (proc.processName.equals(args[start])) {
11966                        procs.add(proc);
11967                    }
11968                }
11969                if (procs.size() <= 0) {
11970                    return null;
11971                }
11972            } else {
11973                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11974            }
11975        }
11976        return procs;
11977    }
11978
11979    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11980            PrintWriter pw, String[] args) {
11981        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11982        if (procs == null) {
11983            pw.println("No process found for: " + args[0]);
11984            return;
11985        }
11986
11987        long uptime = SystemClock.uptimeMillis();
11988        long realtime = SystemClock.elapsedRealtime();
11989        pw.println("Applications Graphics Acceleration Info:");
11990        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11991
11992        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11993            ProcessRecord r = procs.get(i);
11994            if (r.thread != null) {
11995                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11996                pw.flush();
11997                try {
11998                    TransferPipe tp = new TransferPipe();
11999                    try {
12000                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12001                        tp.go(fd);
12002                    } finally {
12003                        tp.kill();
12004                    }
12005                } catch (IOException e) {
12006                    pw.println("Failure while dumping the app: " + r);
12007                    pw.flush();
12008                } catch (RemoteException e) {
12009                    pw.println("Got a RemoteException while dumping the app " + r);
12010                    pw.flush();
12011                }
12012            }
12013        }
12014    }
12015
12016    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12017        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12018        if (procs == null) {
12019            pw.println("No process found for: " + args[0]);
12020            return;
12021        }
12022
12023        pw.println("Applications Database Info:");
12024
12025        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12026            ProcessRecord r = procs.get(i);
12027            if (r.thread != null) {
12028                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12029                pw.flush();
12030                try {
12031                    TransferPipe tp = new TransferPipe();
12032                    try {
12033                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12034                        tp.go(fd);
12035                    } finally {
12036                        tp.kill();
12037                    }
12038                } catch (IOException e) {
12039                    pw.println("Failure while dumping the app: " + r);
12040                    pw.flush();
12041                } catch (RemoteException e) {
12042                    pw.println("Got a RemoteException while dumping the app " + r);
12043                    pw.flush();
12044                }
12045            }
12046        }
12047    }
12048
12049    final static class MemItem {
12050        final boolean isProc;
12051        final String label;
12052        final String shortLabel;
12053        final long pss;
12054        final int id;
12055        final boolean hasActivities;
12056        ArrayList<MemItem> subitems;
12057
12058        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12059                boolean _hasActivities) {
12060            isProc = true;
12061            label = _label;
12062            shortLabel = _shortLabel;
12063            pss = _pss;
12064            id = _id;
12065            hasActivities = _hasActivities;
12066        }
12067
12068        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12069            isProc = false;
12070            label = _label;
12071            shortLabel = _shortLabel;
12072            pss = _pss;
12073            id = _id;
12074            hasActivities = false;
12075        }
12076    }
12077
12078    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12079            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12080        if (sort && !isCompact) {
12081            Collections.sort(items, new Comparator<MemItem>() {
12082                @Override
12083                public int compare(MemItem lhs, MemItem rhs) {
12084                    if (lhs.pss < rhs.pss) {
12085                        return 1;
12086                    } else if (lhs.pss > rhs.pss) {
12087                        return -1;
12088                    }
12089                    return 0;
12090                }
12091            });
12092        }
12093
12094        for (int i=0; i<items.size(); i++) {
12095            MemItem mi = items.get(i);
12096            if (!isCompact) {
12097                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12098            } else if (mi.isProc) {
12099                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12100                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12101                pw.println(mi.hasActivities ? ",a" : ",e");
12102            } else {
12103                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12104                pw.println(mi.pss);
12105            }
12106            if (mi.subitems != null) {
12107                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12108                        true, isCompact);
12109            }
12110        }
12111    }
12112
12113    // These are in KB.
12114    static final long[] DUMP_MEM_BUCKETS = new long[] {
12115        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12116        120*1024, 160*1024, 200*1024,
12117        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12118        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12119    };
12120
12121    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12122            boolean stackLike) {
12123        int start = label.lastIndexOf('.');
12124        if (start >= 0) start++;
12125        else start = 0;
12126        int end = label.length();
12127        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12128            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12129                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12130                out.append(bucket);
12131                out.append(stackLike ? "MB." : "MB ");
12132                out.append(label, start, end);
12133                return;
12134            }
12135        }
12136        out.append(memKB/1024);
12137        out.append(stackLike ? "MB." : "MB ");
12138        out.append(label, start, end);
12139    }
12140
12141    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12142            ProcessList.NATIVE_ADJ,
12143            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12144            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12145            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12146            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12147            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12148    };
12149    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12150            "Native",
12151            "System", "Persistent", "Foreground",
12152            "Visible", "Perceptible",
12153            "Heavy Weight", "Backup",
12154            "A Services", "Home",
12155            "Previous", "B Services", "Cached"
12156    };
12157    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12158            "native",
12159            "sys", "pers", "fore",
12160            "vis", "percept",
12161            "heavy", "backup",
12162            "servicea", "home",
12163            "prev", "serviceb", "cached"
12164    };
12165
12166    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12167            long realtime, boolean isCheckinRequest, boolean isCompact) {
12168        if (isCheckinRequest || isCompact) {
12169            // short checkin version
12170            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12171        } else {
12172            pw.println("Applications Memory Usage (kB):");
12173            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12174        }
12175    }
12176
12177    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12178            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12179        boolean dumpDetails = false;
12180        boolean dumpFullDetails = false;
12181        boolean dumpDalvik = false;
12182        boolean oomOnly = false;
12183        boolean isCompact = false;
12184        boolean localOnly = false;
12185
12186        int opti = 0;
12187        while (opti < args.length) {
12188            String opt = args[opti];
12189            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12190                break;
12191            }
12192            opti++;
12193            if ("-a".equals(opt)) {
12194                dumpDetails = true;
12195                dumpFullDetails = true;
12196                dumpDalvik = true;
12197            } else if ("-d".equals(opt)) {
12198                dumpDalvik = true;
12199            } else if ("-c".equals(opt)) {
12200                isCompact = true;
12201            } else if ("--oom".equals(opt)) {
12202                oomOnly = true;
12203            } else if ("--local".equals(opt)) {
12204                localOnly = true;
12205            } else if ("-h".equals(opt)) {
12206                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12207                pw.println("  -a: include all available information for each process.");
12208                pw.println("  -d: include dalvik details when dumping process details.");
12209                pw.println("  -c: dump in a compact machine-parseable representation.");
12210                pw.println("  --oom: only show processes organized by oom adj.");
12211                pw.println("  --local: only collect details locally, don't call process.");
12212                pw.println("If [process] is specified it can be the name or ");
12213                pw.println("pid of a specific process to dump.");
12214                return;
12215            } else {
12216                pw.println("Unknown argument: " + opt + "; use -h for help");
12217            }
12218        }
12219
12220        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12221        long uptime = SystemClock.uptimeMillis();
12222        long realtime = SystemClock.elapsedRealtime();
12223        final long[] tmpLong = new long[1];
12224
12225        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12226        if (procs == null) {
12227            // No Java processes.  Maybe they want to print a native process.
12228            if (args != null && args.length > opti
12229                    && args[opti].charAt(0) != '-') {
12230                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12231                        = new ArrayList<ProcessCpuTracker.Stats>();
12232                updateCpuStatsNow();
12233                int findPid = -1;
12234                try {
12235                    findPid = Integer.parseInt(args[opti]);
12236                } catch (NumberFormatException e) {
12237                }
12238                synchronized (mProcessCpuThread) {
12239                    final int N = mProcessCpuTracker.countStats();
12240                    for (int i=0; i<N; i++) {
12241                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12242                        if (st.pid == findPid || (st.baseName != null
12243                                && st.baseName.equals(args[opti]))) {
12244                            nativeProcs.add(st);
12245                        }
12246                    }
12247                }
12248                if (nativeProcs.size() > 0) {
12249                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12250                            isCompact);
12251                    Debug.MemoryInfo mi = null;
12252                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12253                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12254                        final int pid = r.pid;
12255                        if (!isCheckinRequest && dumpDetails) {
12256                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12257                        }
12258                        if (mi == null) {
12259                            mi = new Debug.MemoryInfo();
12260                        }
12261                        if (dumpDetails || (!brief && !oomOnly)) {
12262                            Debug.getMemoryInfo(pid, mi);
12263                        } else {
12264                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12265                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12266                        }
12267                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12268                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12269                        if (isCheckinRequest) {
12270                            pw.println();
12271                        }
12272                    }
12273                    return;
12274                }
12275            }
12276            pw.println("No process found for: " + args[opti]);
12277            return;
12278        }
12279
12280        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12281            dumpDetails = true;
12282        }
12283
12284        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12285
12286        String[] innerArgs = new String[args.length-opti];
12287        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12288
12289        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12290        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12291        long nativePss=0, dalvikPss=0, otherPss=0;
12292        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12293
12294        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12295        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12296                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12297
12298        long totalPss = 0;
12299        long cachedPss = 0;
12300
12301        Debug.MemoryInfo mi = null;
12302        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12303            final ProcessRecord r = procs.get(i);
12304            final IApplicationThread thread;
12305            final int pid;
12306            final int oomAdj;
12307            final boolean hasActivities;
12308            synchronized (this) {
12309                thread = r.thread;
12310                pid = r.pid;
12311                oomAdj = r.getSetAdjWithServices();
12312                hasActivities = r.activities.size() > 0;
12313            }
12314            if (thread != null) {
12315                if (!isCheckinRequest && dumpDetails) {
12316                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12317                }
12318                if (mi == null) {
12319                    mi = new Debug.MemoryInfo();
12320                }
12321                if (dumpDetails || (!brief && !oomOnly)) {
12322                    Debug.getMemoryInfo(pid, mi);
12323                } else {
12324                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12325                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12326                }
12327                if (dumpDetails) {
12328                    if (localOnly) {
12329                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12330                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12331                        if (isCheckinRequest) {
12332                            pw.println();
12333                        }
12334                    } else {
12335                        try {
12336                            pw.flush();
12337                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12338                                    dumpDalvik, innerArgs);
12339                        } catch (RemoteException e) {
12340                            if (!isCheckinRequest) {
12341                                pw.println("Got RemoteException!");
12342                                pw.flush();
12343                            }
12344                        }
12345                    }
12346                }
12347
12348                final long myTotalPss = mi.getTotalPss();
12349                final long myTotalUss = mi.getTotalUss();
12350
12351                synchronized (this) {
12352                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12353                        // Record this for posterity if the process has been stable.
12354                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12355                    }
12356                }
12357
12358                if (!isCheckinRequest && mi != null) {
12359                    totalPss += myTotalPss;
12360                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12361                            (hasActivities ? " / activities)" : ")"),
12362                            r.processName, myTotalPss, pid, hasActivities);
12363                    procMems.add(pssItem);
12364                    procMemsMap.put(pid, pssItem);
12365
12366                    nativePss += mi.nativePss;
12367                    dalvikPss += mi.dalvikPss;
12368                    otherPss += mi.otherPss;
12369                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12370                        long mem = mi.getOtherPss(j);
12371                        miscPss[j] += mem;
12372                        otherPss -= mem;
12373                    }
12374
12375                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12376                        cachedPss += myTotalPss;
12377                    }
12378
12379                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12380                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12381                                || oomIndex == (oomPss.length-1)) {
12382                            oomPss[oomIndex] += myTotalPss;
12383                            if (oomProcs[oomIndex] == null) {
12384                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12385                            }
12386                            oomProcs[oomIndex].add(pssItem);
12387                            break;
12388                        }
12389                    }
12390                }
12391            }
12392        }
12393
12394        if (!isCheckinRequest && procs.size() > 1) {
12395            // If we are showing aggregations, also look for native processes to
12396            // include so that our aggregations are more accurate.
12397            updateCpuStatsNow();
12398            synchronized (mProcessCpuThread) {
12399                final int N = mProcessCpuTracker.countStats();
12400                for (int i=0; i<N; i++) {
12401                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12402                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12403                        if (mi == null) {
12404                            mi = new Debug.MemoryInfo();
12405                        }
12406                        if (!brief && !oomOnly) {
12407                            Debug.getMemoryInfo(st.pid, mi);
12408                        } else {
12409                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12410                            mi.nativePrivateDirty = (int)tmpLong[0];
12411                        }
12412
12413                        final long myTotalPss = mi.getTotalPss();
12414                        totalPss += myTotalPss;
12415
12416                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12417                                st.name, myTotalPss, st.pid, false);
12418                        procMems.add(pssItem);
12419
12420                        nativePss += mi.nativePss;
12421                        dalvikPss += mi.dalvikPss;
12422                        otherPss += mi.otherPss;
12423                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12424                            long mem = mi.getOtherPss(j);
12425                            miscPss[j] += mem;
12426                            otherPss -= mem;
12427                        }
12428                        oomPss[0] += myTotalPss;
12429                        if (oomProcs[0] == null) {
12430                            oomProcs[0] = new ArrayList<MemItem>();
12431                        }
12432                        oomProcs[0].add(pssItem);
12433                    }
12434                }
12435            }
12436
12437            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12438
12439            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12440            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12441            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12442            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12443                String label = Debug.MemoryInfo.getOtherLabel(j);
12444                catMems.add(new MemItem(label, label, miscPss[j], j));
12445            }
12446
12447            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12448            for (int j=0; j<oomPss.length; j++) {
12449                if (oomPss[j] != 0) {
12450                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12451                            : DUMP_MEM_OOM_LABEL[j];
12452                    MemItem item = new MemItem(label, label, oomPss[j],
12453                            DUMP_MEM_OOM_ADJ[j]);
12454                    item.subitems = oomProcs[j];
12455                    oomMems.add(item);
12456                }
12457            }
12458
12459            if (!brief && !oomOnly && !isCompact) {
12460                pw.println();
12461                pw.println("Total PSS by process:");
12462                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12463                pw.println();
12464            }
12465            if (!isCompact) {
12466                pw.println("Total PSS by OOM adjustment:");
12467            }
12468            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12469            if (!brief && !oomOnly) {
12470                PrintWriter out = categoryPw != null ? categoryPw : pw;
12471                if (!isCompact) {
12472                    out.println();
12473                    out.println("Total PSS by category:");
12474                }
12475                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12476            }
12477            if (!isCompact) {
12478                pw.println();
12479            }
12480            MemInfoReader memInfo = new MemInfoReader();
12481            memInfo.readMemInfo();
12482            if (!brief) {
12483                if (!isCompact) {
12484                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12485                    pw.print(" kB (status ");
12486                    switch (mLastMemoryLevel) {
12487                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12488                            pw.println("normal)");
12489                            break;
12490                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12491                            pw.println("moderate)");
12492                            break;
12493                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12494                            pw.println("low)");
12495                            break;
12496                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12497                            pw.println("critical)");
12498                            break;
12499                        default:
12500                            pw.print(mLastMemoryLevel);
12501                            pw.println(")");
12502                            break;
12503                    }
12504                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12505                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12506                            pw.print(cachedPss); pw.print(" cached pss + ");
12507                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12508                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12509                } else {
12510                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12511                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12512                            + memInfo.getFreeSizeKb()); pw.print(",");
12513                    pw.println(totalPss - cachedPss);
12514                }
12515            }
12516            if (!isCompact) {
12517                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12518                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12519                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12520                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12521                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12522                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12523                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12524                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12525                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12526                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12527                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12528            }
12529            if (!brief) {
12530                if (memInfo.getZramTotalSizeKb() != 0) {
12531                    if (!isCompact) {
12532                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12533                                pw.print(" kB physical used for ");
12534                                pw.print(memInfo.getSwapTotalSizeKb()
12535                                        - memInfo.getSwapFreeSizeKb());
12536                                pw.print(" kB in swap (");
12537                                pw.print(memInfo.getSwapTotalSizeKb());
12538                                pw.println(" kB total swap)");
12539                    } else {
12540                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12541                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12542                                pw.println(memInfo.getSwapFreeSizeKb());
12543                    }
12544                }
12545                final int[] SINGLE_LONG_FORMAT = new int[] {
12546                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12547                };
12548                long[] longOut = new long[1];
12549                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12550                        SINGLE_LONG_FORMAT, null, longOut, null);
12551                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12552                longOut[0] = 0;
12553                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12554                        SINGLE_LONG_FORMAT, null, longOut, null);
12555                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12556                longOut[0] = 0;
12557                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12558                        SINGLE_LONG_FORMAT, null, longOut, null);
12559                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12560                longOut[0] = 0;
12561                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12562                        SINGLE_LONG_FORMAT, null, longOut, null);
12563                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12564                if (!isCompact) {
12565                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12566                        pw.print("      KSM: "); pw.print(sharing);
12567                                pw.print(" kB saved from shared ");
12568                                pw.print(shared); pw.println(" kB");
12569                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12570                                pw.print(voltile); pw.println(" kB volatile");
12571                    }
12572                    pw.print("   Tuning: ");
12573                    pw.print(ActivityManager.staticGetMemoryClass());
12574                    pw.print(" (large ");
12575                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12576                    pw.print("), oom ");
12577                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12578                    pw.print(" kB");
12579                    pw.print(", restore limit ");
12580                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12581                    pw.print(" kB");
12582                    if (ActivityManager.isLowRamDeviceStatic()) {
12583                        pw.print(" (low-ram)");
12584                    }
12585                    if (ActivityManager.isHighEndGfx()) {
12586                        pw.print(" (high-end-gfx)");
12587                    }
12588                    pw.println();
12589                } else {
12590                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12591                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12592                    pw.println(voltile);
12593                    pw.print("tuning,");
12594                    pw.print(ActivityManager.staticGetMemoryClass());
12595                    pw.print(',');
12596                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12597                    pw.print(',');
12598                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12599                    if (ActivityManager.isLowRamDeviceStatic()) {
12600                        pw.print(",low-ram");
12601                    }
12602                    if (ActivityManager.isHighEndGfx()) {
12603                        pw.print(",high-end-gfx");
12604                    }
12605                    pw.println();
12606                }
12607            }
12608        }
12609    }
12610
12611    /**
12612     * Searches array of arguments for the specified string
12613     * @param args array of argument strings
12614     * @param value value to search for
12615     * @return true if the value is contained in the array
12616     */
12617    private static boolean scanArgs(String[] args, String value) {
12618        if (args != null) {
12619            for (String arg : args) {
12620                if (value.equals(arg)) {
12621                    return true;
12622                }
12623            }
12624        }
12625        return false;
12626    }
12627
12628    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12629            ContentProviderRecord cpr, boolean always) {
12630        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12631
12632        if (!inLaunching || always) {
12633            synchronized (cpr) {
12634                cpr.launchingApp = null;
12635                cpr.notifyAll();
12636            }
12637            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12638            String names[] = cpr.info.authority.split(";");
12639            for (int j = 0; j < names.length; j++) {
12640                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12641            }
12642        }
12643
12644        for (int i=0; i<cpr.connections.size(); i++) {
12645            ContentProviderConnection conn = cpr.connections.get(i);
12646            if (conn.waiting) {
12647                // If this connection is waiting for the provider, then we don't
12648                // need to mess with its process unless we are always removing
12649                // or for some reason the provider is not currently launching.
12650                if (inLaunching && !always) {
12651                    continue;
12652                }
12653            }
12654            ProcessRecord capp = conn.client;
12655            conn.dead = true;
12656            if (conn.stableCount > 0) {
12657                if (!capp.persistent && capp.thread != null
12658                        && capp.pid != 0
12659                        && capp.pid != MY_PID) {
12660                    killUnneededProcessLocked(capp, "depends on provider "
12661                            + cpr.name.flattenToShortString()
12662                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12663                }
12664            } else if (capp.thread != null && conn.provider.provider != null) {
12665                try {
12666                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12667                } catch (RemoteException e) {
12668                }
12669                // In the protocol here, we don't expect the client to correctly
12670                // clean up this connection, we'll just remove it.
12671                cpr.connections.remove(i);
12672                conn.client.conProviders.remove(conn);
12673            }
12674        }
12675
12676        if (inLaunching && always) {
12677            mLaunchingProviders.remove(cpr);
12678        }
12679        return inLaunching;
12680    }
12681
12682    /**
12683     * Main code for cleaning up a process when it has gone away.  This is
12684     * called both as a result of the process dying, or directly when stopping
12685     * a process when running in single process mode.
12686     */
12687    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12688            boolean restarting, boolean allowRestart, int index) {
12689        if (index >= 0) {
12690            removeLruProcessLocked(app);
12691            ProcessList.remove(app.pid);
12692        }
12693
12694        mProcessesToGc.remove(app);
12695        mPendingPssProcesses.remove(app);
12696
12697        // Dismiss any open dialogs.
12698        if (app.crashDialog != null && !app.forceCrashReport) {
12699            app.crashDialog.dismiss();
12700            app.crashDialog = null;
12701        }
12702        if (app.anrDialog != null) {
12703            app.anrDialog.dismiss();
12704            app.anrDialog = null;
12705        }
12706        if (app.waitDialog != null) {
12707            app.waitDialog.dismiss();
12708            app.waitDialog = null;
12709        }
12710
12711        app.crashing = false;
12712        app.notResponding = false;
12713
12714        app.resetPackageList(mProcessStats);
12715        app.unlinkDeathRecipient();
12716        app.makeInactive(mProcessStats);
12717        app.forcingToForeground = null;
12718        updateProcessForegroundLocked(app, false, false);
12719        app.foregroundActivities = false;
12720        app.hasShownUi = false;
12721        app.treatLikeActivity = false;
12722        app.hasAboveClient = false;
12723        app.hasClientActivities = false;
12724
12725        mServices.killServicesLocked(app, allowRestart);
12726
12727        boolean restart = false;
12728
12729        // Remove published content providers.
12730        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12731            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12732            final boolean always = app.bad || !allowRestart;
12733            if (removeDyingProviderLocked(app, cpr, always) || always) {
12734                // We left the provider in the launching list, need to
12735                // restart it.
12736                restart = true;
12737            }
12738
12739            cpr.provider = null;
12740            cpr.proc = null;
12741        }
12742        app.pubProviders.clear();
12743
12744        // Take care of any launching providers waiting for this process.
12745        if (checkAppInLaunchingProvidersLocked(app, false)) {
12746            restart = true;
12747        }
12748
12749        // Unregister from connected content providers.
12750        if (!app.conProviders.isEmpty()) {
12751            for (int i=0; i<app.conProviders.size(); i++) {
12752                ContentProviderConnection conn = app.conProviders.get(i);
12753                conn.provider.connections.remove(conn);
12754            }
12755            app.conProviders.clear();
12756        }
12757
12758        // At this point there may be remaining entries in mLaunchingProviders
12759        // where we were the only one waiting, so they are no longer of use.
12760        // Look for these and clean up if found.
12761        // XXX Commented out for now.  Trying to figure out a way to reproduce
12762        // the actual situation to identify what is actually going on.
12763        if (false) {
12764            for (int i=0; i<mLaunchingProviders.size(); i++) {
12765                ContentProviderRecord cpr = (ContentProviderRecord)
12766                        mLaunchingProviders.get(i);
12767                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12768                    synchronized (cpr) {
12769                        cpr.launchingApp = null;
12770                        cpr.notifyAll();
12771                    }
12772                }
12773            }
12774        }
12775
12776        skipCurrentReceiverLocked(app);
12777
12778        // Unregister any receivers.
12779        for (int i=app.receivers.size()-1; i>=0; i--) {
12780            removeReceiverLocked(app.receivers.valueAt(i));
12781        }
12782        app.receivers.clear();
12783
12784        // If the app is undergoing backup, tell the backup manager about it
12785        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12786            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12787                    + mBackupTarget.appInfo + " died during backup");
12788            try {
12789                IBackupManager bm = IBackupManager.Stub.asInterface(
12790                        ServiceManager.getService(Context.BACKUP_SERVICE));
12791                bm.agentDisconnected(app.info.packageName);
12792            } catch (RemoteException e) {
12793                // can't happen; backup manager is local
12794            }
12795        }
12796
12797        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12798            ProcessChangeItem item = mPendingProcessChanges.get(i);
12799            if (item.pid == app.pid) {
12800                mPendingProcessChanges.remove(i);
12801                mAvailProcessChanges.add(item);
12802            }
12803        }
12804        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12805
12806        // If the caller is restarting this app, then leave it in its
12807        // current lists and let the caller take care of it.
12808        if (restarting) {
12809            return;
12810        }
12811
12812        if (!app.persistent || app.isolated) {
12813            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12814                    "Removing non-persistent process during cleanup: " + app);
12815            mProcessNames.remove(app.processName, app.uid);
12816            mIsolatedProcesses.remove(app.uid);
12817            if (mHeavyWeightProcess == app) {
12818                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12819                        mHeavyWeightProcess.userId, 0));
12820                mHeavyWeightProcess = null;
12821            }
12822        } else if (!app.removed) {
12823            // This app is persistent, so we need to keep its record around.
12824            // If it is not already on the pending app list, add it there
12825            // and start a new process for it.
12826            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12827                mPersistentStartingProcesses.add(app);
12828                restart = true;
12829            }
12830        }
12831        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12832                "Clean-up removing on hold: " + app);
12833        mProcessesOnHold.remove(app);
12834
12835        if (app == mHomeProcess) {
12836            mHomeProcess = null;
12837        }
12838        if (app == mPreviousProcess) {
12839            mPreviousProcess = null;
12840        }
12841
12842        if (restart && !app.isolated) {
12843            // We have components that still need to be running in the
12844            // process, so re-launch it.
12845            mProcessNames.put(app.processName, app.uid, app);
12846            startProcessLocked(app, "restart", app.processName);
12847        } else if (app.pid > 0 && app.pid != MY_PID) {
12848            // Goodbye!
12849            boolean removed;
12850            synchronized (mPidsSelfLocked) {
12851                mPidsSelfLocked.remove(app.pid);
12852                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12853            }
12854            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12855                    app.processName, app.info.uid);
12856            if (app.isolated) {
12857                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12858            }
12859            app.setPid(0);
12860        }
12861    }
12862
12863    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12864        // Look through the content providers we are waiting to have launched,
12865        // and if any run in this process then either schedule a restart of
12866        // the process or kill the client waiting for it if this process has
12867        // gone bad.
12868        int NL = mLaunchingProviders.size();
12869        boolean restart = false;
12870        for (int i=0; i<NL; i++) {
12871            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12872            if (cpr.launchingApp == app) {
12873                if (!alwaysBad && !app.bad) {
12874                    restart = true;
12875                } else {
12876                    removeDyingProviderLocked(app, cpr, true);
12877                    // cpr should have been removed from mLaunchingProviders
12878                    NL = mLaunchingProviders.size();
12879                    i--;
12880                }
12881            }
12882        }
12883        return restart;
12884    }
12885
12886    // =========================================================
12887    // SERVICES
12888    // =========================================================
12889
12890    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12891            int flags) {
12892        enforceNotIsolatedCaller("getServices");
12893        synchronized (this) {
12894            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12895        }
12896    }
12897
12898    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12899        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12900        synchronized (this) {
12901            return mServices.getRunningServiceControlPanelLocked(name);
12902        }
12903    }
12904
12905    public ComponentName startService(IApplicationThread caller, Intent service,
12906            String resolvedType, int userId) {
12907        enforceNotIsolatedCaller("startService");
12908        // Refuse possible leaked file descriptors
12909        if (service != null && service.hasFileDescriptors() == true) {
12910            throw new IllegalArgumentException("File descriptors passed in Intent");
12911        }
12912
12913        if (DEBUG_SERVICE)
12914            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12915        synchronized(this) {
12916            final int callingPid = Binder.getCallingPid();
12917            final int callingUid = Binder.getCallingUid();
12918            final long origId = Binder.clearCallingIdentity();
12919            ComponentName res = mServices.startServiceLocked(caller, service,
12920                    resolvedType, callingPid, callingUid, userId);
12921            Binder.restoreCallingIdentity(origId);
12922            return res;
12923        }
12924    }
12925
12926    ComponentName startServiceInPackage(int uid,
12927            Intent service, String resolvedType, int userId) {
12928        synchronized(this) {
12929            if (DEBUG_SERVICE)
12930                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12931            final long origId = Binder.clearCallingIdentity();
12932            ComponentName res = mServices.startServiceLocked(null, service,
12933                    resolvedType, -1, uid, userId);
12934            Binder.restoreCallingIdentity(origId);
12935            return res;
12936        }
12937    }
12938
12939    public int stopService(IApplicationThread caller, Intent service,
12940            String resolvedType, int userId) {
12941        enforceNotIsolatedCaller("stopService");
12942        // Refuse possible leaked file descriptors
12943        if (service != null && service.hasFileDescriptors() == true) {
12944            throw new IllegalArgumentException("File descriptors passed in Intent");
12945        }
12946
12947        synchronized(this) {
12948            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12949        }
12950    }
12951
12952    public IBinder peekService(Intent service, String resolvedType) {
12953        enforceNotIsolatedCaller("peekService");
12954        // Refuse possible leaked file descriptors
12955        if (service != null && service.hasFileDescriptors() == true) {
12956            throw new IllegalArgumentException("File descriptors passed in Intent");
12957        }
12958        synchronized(this) {
12959            return mServices.peekServiceLocked(service, resolvedType);
12960        }
12961    }
12962
12963    public boolean stopServiceToken(ComponentName className, IBinder token,
12964            int startId) {
12965        synchronized(this) {
12966            return mServices.stopServiceTokenLocked(className, token, startId);
12967        }
12968    }
12969
12970    public void setServiceForeground(ComponentName className, IBinder token,
12971            int id, Notification notification, boolean removeNotification) {
12972        synchronized(this) {
12973            mServices.setServiceForegroundLocked(className, token, id, notification,
12974                    removeNotification);
12975        }
12976    }
12977
12978    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12979            boolean requireFull, String name, String callerPackage) {
12980        final int callingUserId = UserHandle.getUserId(callingUid);
12981        if (callingUserId != userId) {
12982            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12983                if ((requireFull || checkComponentPermission(
12984                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12985                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12986                        && checkComponentPermission(
12987                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12988                                callingPid, callingUid, -1, true)
12989                                != PackageManager.PERMISSION_GRANTED) {
12990                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12991                        // In this case, they would like to just execute as their
12992                        // owner user instead of failing.
12993                        userId = callingUserId;
12994                    } else {
12995                        StringBuilder builder = new StringBuilder(128);
12996                        builder.append("Permission Denial: ");
12997                        builder.append(name);
12998                        if (callerPackage != null) {
12999                            builder.append(" from ");
13000                            builder.append(callerPackage);
13001                        }
13002                        builder.append(" asks to run as user ");
13003                        builder.append(userId);
13004                        builder.append(" but is calling from user ");
13005                        builder.append(UserHandle.getUserId(callingUid));
13006                        builder.append("; this requires ");
13007                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13008                        if (!requireFull) {
13009                            builder.append(" or ");
13010                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13011                        }
13012                        String msg = builder.toString();
13013                        Slog.w(TAG, msg);
13014                        throw new SecurityException(msg);
13015                    }
13016                }
13017            }
13018            if (userId == UserHandle.USER_CURRENT
13019                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13020                // Note that we may be accessing this outside of a lock...
13021                // shouldn't be a big deal, if this is being called outside
13022                // of a locked context there is intrinsically a race with
13023                // the value the caller will receive and someone else changing it.
13024                userId = mCurrentUserId;
13025            }
13026            if (!allowAll && userId < 0) {
13027                throw new IllegalArgumentException(
13028                        "Call does not support special user #" + userId);
13029            }
13030        }
13031        return userId;
13032    }
13033
13034    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13035            String className, int flags) {
13036        boolean result = false;
13037        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13038            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13039                if (ActivityManager.checkUidPermission(
13040                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13041                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13042                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13043                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13044                            + " requests FLAG_SINGLE_USER, but app does not hold "
13045                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13046                    Slog.w(TAG, msg);
13047                    throw new SecurityException(msg);
13048                }
13049                result = true;
13050            }
13051        } else if (componentProcessName == aInfo.packageName) {
13052            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13053        } else if ("system".equals(componentProcessName)) {
13054            result = true;
13055        }
13056        if (DEBUG_MU) {
13057            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13058                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13059        }
13060        return result;
13061    }
13062
13063    public int bindService(IApplicationThread caller, IBinder token,
13064            Intent service, String resolvedType,
13065            IServiceConnection connection, int flags, int userId) {
13066        enforceNotIsolatedCaller("bindService");
13067        // Refuse possible leaked file descriptors
13068        if (service != null && service.hasFileDescriptors() == true) {
13069            throw new IllegalArgumentException("File descriptors passed in Intent");
13070        }
13071
13072        synchronized(this) {
13073            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13074                    connection, flags, userId);
13075        }
13076    }
13077
13078    public boolean unbindService(IServiceConnection connection) {
13079        synchronized (this) {
13080            return mServices.unbindServiceLocked(connection);
13081        }
13082    }
13083
13084    public void publishService(IBinder token, Intent intent, IBinder service) {
13085        // Refuse possible leaked file descriptors
13086        if (intent != null && intent.hasFileDescriptors() == true) {
13087            throw new IllegalArgumentException("File descriptors passed in Intent");
13088        }
13089
13090        synchronized(this) {
13091            if (!(token instanceof ServiceRecord)) {
13092                throw new IllegalArgumentException("Invalid service token");
13093            }
13094            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13095        }
13096    }
13097
13098    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13099        // Refuse possible leaked file descriptors
13100        if (intent != null && intent.hasFileDescriptors() == true) {
13101            throw new IllegalArgumentException("File descriptors passed in Intent");
13102        }
13103
13104        synchronized(this) {
13105            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13106        }
13107    }
13108
13109    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13110        synchronized(this) {
13111            if (!(token instanceof ServiceRecord)) {
13112                throw new IllegalArgumentException("Invalid service token");
13113            }
13114            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13115        }
13116    }
13117
13118    // =========================================================
13119    // BACKUP AND RESTORE
13120    // =========================================================
13121
13122    // Cause the target app to be launched if necessary and its backup agent
13123    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13124    // activity manager to announce its creation.
13125    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13126        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13127        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13128
13129        synchronized(this) {
13130            // !!! TODO: currently no check here that we're already bound
13131            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13132            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13133            synchronized (stats) {
13134                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13135            }
13136
13137            // Backup agent is now in use, its package can't be stopped.
13138            try {
13139                AppGlobals.getPackageManager().setPackageStoppedState(
13140                        app.packageName, false, UserHandle.getUserId(app.uid));
13141            } catch (RemoteException e) {
13142            } catch (IllegalArgumentException e) {
13143                Slog.w(TAG, "Failed trying to unstop package "
13144                        + app.packageName + ": " + e);
13145            }
13146
13147            BackupRecord r = new BackupRecord(ss, app, backupMode);
13148            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13149                    ? new ComponentName(app.packageName, app.backupAgentName)
13150                    : new ComponentName("android", "FullBackupAgent");
13151            // startProcessLocked() returns existing proc's record if it's already running
13152            ProcessRecord proc = startProcessLocked(app.processName, app,
13153                    false, 0, "backup", hostingName, false, false, false);
13154            if (proc == null) {
13155                Slog.e(TAG, "Unable to start backup agent process " + r);
13156                return false;
13157            }
13158
13159            r.app = proc;
13160            mBackupTarget = r;
13161            mBackupAppName = app.packageName;
13162
13163            // Try not to kill the process during backup
13164            updateOomAdjLocked(proc);
13165
13166            // If the process is already attached, schedule the creation of the backup agent now.
13167            // If it is not yet live, this will be done when it attaches to the framework.
13168            if (proc.thread != null) {
13169                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13170                try {
13171                    proc.thread.scheduleCreateBackupAgent(app,
13172                            compatibilityInfoForPackageLocked(app), backupMode);
13173                } catch (RemoteException e) {
13174                    // Will time out on the backup manager side
13175                }
13176            } else {
13177                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13178            }
13179            // Invariants: at this point, the target app process exists and the application
13180            // is either already running or in the process of coming up.  mBackupTarget and
13181            // mBackupAppName describe the app, so that when it binds back to the AM we
13182            // know that it's scheduled for a backup-agent operation.
13183        }
13184
13185        return true;
13186    }
13187
13188    @Override
13189    public void clearPendingBackup() {
13190        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13191        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13192
13193        synchronized (this) {
13194            mBackupTarget = null;
13195            mBackupAppName = null;
13196        }
13197    }
13198
13199    // A backup agent has just come up
13200    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13201        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13202                + " = " + agent);
13203
13204        synchronized(this) {
13205            if (!agentPackageName.equals(mBackupAppName)) {
13206                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13207                return;
13208            }
13209        }
13210
13211        long oldIdent = Binder.clearCallingIdentity();
13212        try {
13213            IBackupManager bm = IBackupManager.Stub.asInterface(
13214                    ServiceManager.getService(Context.BACKUP_SERVICE));
13215            bm.agentConnected(agentPackageName, agent);
13216        } catch (RemoteException e) {
13217            // can't happen; the backup manager service is local
13218        } catch (Exception e) {
13219            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13220            e.printStackTrace();
13221        } finally {
13222            Binder.restoreCallingIdentity(oldIdent);
13223        }
13224    }
13225
13226    // done with this agent
13227    public void unbindBackupAgent(ApplicationInfo appInfo) {
13228        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13229        if (appInfo == null) {
13230            Slog.w(TAG, "unbind backup agent for null app");
13231            return;
13232        }
13233
13234        synchronized(this) {
13235            try {
13236                if (mBackupAppName == null) {
13237                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13238                    return;
13239                }
13240
13241                if (!mBackupAppName.equals(appInfo.packageName)) {
13242                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13243                    return;
13244                }
13245
13246                // Not backing this app up any more; reset its OOM adjustment
13247                final ProcessRecord proc = mBackupTarget.app;
13248                updateOomAdjLocked(proc);
13249
13250                // If the app crashed during backup, 'thread' will be null here
13251                if (proc.thread != null) {
13252                    try {
13253                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13254                                compatibilityInfoForPackageLocked(appInfo));
13255                    } catch (Exception e) {
13256                        Slog.e(TAG, "Exception when unbinding backup agent:");
13257                        e.printStackTrace();
13258                    }
13259                }
13260            } finally {
13261                mBackupTarget = null;
13262                mBackupAppName = null;
13263            }
13264        }
13265    }
13266    // =========================================================
13267    // BROADCASTS
13268    // =========================================================
13269
13270    private final List getStickiesLocked(String action, IntentFilter filter,
13271            List cur, int userId) {
13272        final ContentResolver resolver = mContext.getContentResolver();
13273        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13274        if (stickies == null) {
13275            return cur;
13276        }
13277        final ArrayList<Intent> list = stickies.get(action);
13278        if (list == null) {
13279            return cur;
13280        }
13281        int N = list.size();
13282        for (int i=0; i<N; i++) {
13283            Intent intent = list.get(i);
13284            if (filter.match(resolver, intent, true, TAG) >= 0) {
13285                if (cur == null) {
13286                    cur = new ArrayList<Intent>();
13287                }
13288                cur.add(intent);
13289            }
13290        }
13291        return cur;
13292    }
13293
13294    boolean isPendingBroadcastProcessLocked(int pid) {
13295        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13296                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13297    }
13298
13299    void skipPendingBroadcastLocked(int pid) {
13300            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13301            for (BroadcastQueue queue : mBroadcastQueues) {
13302                queue.skipPendingBroadcastLocked(pid);
13303            }
13304    }
13305
13306    // The app just attached; send any pending broadcasts that it should receive
13307    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13308        boolean didSomething = false;
13309        for (BroadcastQueue queue : mBroadcastQueues) {
13310            didSomething |= queue.sendPendingBroadcastsLocked(app);
13311        }
13312        return didSomething;
13313    }
13314
13315    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13316            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13317        enforceNotIsolatedCaller("registerReceiver");
13318        int callingUid;
13319        int callingPid;
13320        synchronized(this) {
13321            ProcessRecord callerApp = null;
13322            if (caller != null) {
13323                callerApp = getRecordForAppLocked(caller);
13324                if (callerApp == null) {
13325                    throw new SecurityException(
13326                            "Unable to find app for caller " + caller
13327                            + " (pid=" + Binder.getCallingPid()
13328                            + ") when registering receiver " + receiver);
13329                }
13330                if (callerApp.info.uid != Process.SYSTEM_UID &&
13331                        !callerApp.pkgList.containsKey(callerPackage) &&
13332                        !"android".equals(callerPackage)) {
13333                    throw new SecurityException("Given caller package " + callerPackage
13334                            + " is not running in process " + callerApp);
13335                }
13336                callingUid = callerApp.info.uid;
13337                callingPid = callerApp.pid;
13338            } else {
13339                callerPackage = null;
13340                callingUid = Binder.getCallingUid();
13341                callingPid = Binder.getCallingPid();
13342            }
13343
13344            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13345                    true, true, "registerReceiver", callerPackage);
13346
13347            List allSticky = null;
13348
13349            // Look for any matching sticky broadcasts...
13350            Iterator actions = filter.actionsIterator();
13351            if (actions != null) {
13352                while (actions.hasNext()) {
13353                    String action = (String)actions.next();
13354                    allSticky = getStickiesLocked(action, filter, allSticky,
13355                            UserHandle.USER_ALL);
13356                    allSticky = getStickiesLocked(action, filter, allSticky,
13357                            UserHandle.getUserId(callingUid));
13358                }
13359            } else {
13360                allSticky = getStickiesLocked(null, filter, allSticky,
13361                        UserHandle.USER_ALL);
13362                allSticky = getStickiesLocked(null, filter, allSticky,
13363                        UserHandle.getUserId(callingUid));
13364            }
13365
13366            // The first sticky in the list is returned directly back to
13367            // the client.
13368            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13369
13370            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13371                    + ": " + sticky);
13372
13373            if (receiver == null) {
13374                return sticky;
13375            }
13376
13377            ReceiverList rl
13378                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13379            if (rl == null) {
13380                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13381                        userId, receiver);
13382                if (rl.app != null) {
13383                    rl.app.receivers.add(rl);
13384                } else {
13385                    try {
13386                        receiver.asBinder().linkToDeath(rl, 0);
13387                    } catch (RemoteException e) {
13388                        return sticky;
13389                    }
13390                    rl.linkedToDeath = true;
13391                }
13392                mRegisteredReceivers.put(receiver.asBinder(), rl);
13393            } else if (rl.uid != callingUid) {
13394                throw new IllegalArgumentException(
13395                        "Receiver requested to register for uid " + callingUid
13396                        + " was previously registered for uid " + rl.uid);
13397            } else if (rl.pid != callingPid) {
13398                throw new IllegalArgumentException(
13399                        "Receiver requested to register for pid " + callingPid
13400                        + " was previously registered for pid " + rl.pid);
13401            } else if (rl.userId != userId) {
13402                throw new IllegalArgumentException(
13403                        "Receiver requested to register for user " + userId
13404                        + " was previously registered for user " + rl.userId);
13405            }
13406            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13407                    permission, callingUid, userId);
13408            rl.add(bf);
13409            if (!bf.debugCheck()) {
13410                Slog.w(TAG, "==> For Dynamic broadast");
13411            }
13412            mReceiverResolver.addFilter(bf);
13413
13414            // Enqueue broadcasts for all existing stickies that match
13415            // this filter.
13416            if (allSticky != null) {
13417                ArrayList receivers = new ArrayList();
13418                receivers.add(bf);
13419
13420                int N = allSticky.size();
13421                for (int i=0; i<N; i++) {
13422                    Intent intent = (Intent)allSticky.get(i);
13423                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13424                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13425                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13426                            null, null, false, true, true, -1);
13427                    queue.enqueueParallelBroadcastLocked(r);
13428                    queue.scheduleBroadcastsLocked();
13429                }
13430            }
13431
13432            return sticky;
13433        }
13434    }
13435
13436    public void unregisterReceiver(IIntentReceiver receiver) {
13437        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13438
13439        final long origId = Binder.clearCallingIdentity();
13440        try {
13441            boolean doTrim = false;
13442
13443            synchronized(this) {
13444                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13445                if (rl != null) {
13446                    if (rl.curBroadcast != null) {
13447                        BroadcastRecord r = rl.curBroadcast;
13448                        final boolean doNext = finishReceiverLocked(
13449                                receiver.asBinder(), r.resultCode, r.resultData,
13450                                r.resultExtras, r.resultAbort);
13451                        if (doNext) {
13452                            doTrim = true;
13453                            r.queue.processNextBroadcast(false);
13454                        }
13455                    }
13456
13457                    if (rl.app != null) {
13458                        rl.app.receivers.remove(rl);
13459                    }
13460                    removeReceiverLocked(rl);
13461                    if (rl.linkedToDeath) {
13462                        rl.linkedToDeath = false;
13463                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13464                    }
13465                }
13466            }
13467
13468            // If we actually concluded any broadcasts, we might now be able
13469            // to trim the recipients' apps from our working set
13470            if (doTrim) {
13471                trimApplications();
13472                return;
13473            }
13474
13475        } finally {
13476            Binder.restoreCallingIdentity(origId);
13477        }
13478    }
13479
13480    void removeReceiverLocked(ReceiverList rl) {
13481        mRegisteredReceivers.remove(rl.receiver.asBinder());
13482        int N = rl.size();
13483        for (int i=0; i<N; i++) {
13484            mReceiverResolver.removeFilter(rl.get(i));
13485        }
13486    }
13487
13488    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13489        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13490            ProcessRecord r = mLruProcesses.get(i);
13491            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13492                try {
13493                    r.thread.dispatchPackageBroadcast(cmd, packages);
13494                } catch (RemoteException ex) {
13495                }
13496            }
13497        }
13498    }
13499
13500    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13501            int[] users) {
13502        List<ResolveInfo> receivers = null;
13503        try {
13504            HashSet<ComponentName> singleUserReceivers = null;
13505            boolean scannedFirstReceivers = false;
13506            for (int user : users) {
13507                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13508                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13509                if (user != 0 && newReceivers != null) {
13510                    // If this is not the primary user, we need to check for
13511                    // any receivers that should be filtered out.
13512                    for (int i=0; i<newReceivers.size(); i++) {
13513                        ResolveInfo ri = newReceivers.get(i);
13514                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13515                            newReceivers.remove(i);
13516                            i--;
13517                        }
13518                    }
13519                }
13520                if (newReceivers != null && newReceivers.size() == 0) {
13521                    newReceivers = null;
13522                }
13523                if (receivers == null) {
13524                    receivers = newReceivers;
13525                } else if (newReceivers != null) {
13526                    // We need to concatenate the additional receivers
13527                    // found with what we have do far.  This would be easy,
13528                    // but we also need to de-dup any receivers that are
13529                    // singleUser.
13530                    if (!scannedFirstReceivers) {
13531                        // Collect any single user receivers we had already retrieved.
13532                        scannedFirstReceivers = true;
13533                        for (int i=0; i<receivers.size(); i++) {
13534                            ResolveInfo ri = receivers.get(i);
13535                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13536                                ComponentName cn = new ComponentName(
13537                                        ri.activityInfo.packageName, ri.activityInfo.name);
13538                                if (singleUserReceivers == null) {
13539                                    singleUserReceivers = new HashSet<ComponentName>();
13540                                }
13541                                singleUserReceivers.add(cn);
13542                            }
13543                        }
13544                    }
13545                    // Add the new results to the existing results, tracking
13546                    // and de-dupping single user receivers.
13547                    for (int i=0; i<newReceivers.size(); i++) {
13548                        ResolveInfo ri = newReceivers.get(i);
13549                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13550                            ComponentName cn = new ComponentName(
13551                                    ri.activityInfo.packageName, ri.activityInfo.name);
13552                            if (singleUserReceivers == null) {
13553                                singleUserReceivers = new HashSet<ComponentName>();
13554                            }
13555                            if (!singleUserReceivers.contains(cn)) {
13556                                singleUserReceivers.add(cn);
13557                                receivers.add(ri);
13558                            }
13559                        } else {
13560                            receivers.add(ri);
13561                        }
13562                    }
13563                }
13564            }
13565        } catch (RemoteException ex) {
13566            // pm is in same process, this will never happen.
13567        }
13568        return receivers;
13569    }
13570
13571    private final int broadcastIntentLocked(ProcessRecord callerApp,
13572            String callerPackage, Intent intent, String resolvedType,
13573            IIntentReceiver resultTo, int resultCode, String resultData,
13574            Bundle map, String requiredPermission, int appOp,
13575            boolean ordered, boolean sticky, int callingPid, int callingUid,
13576            int userId) {
13577        intent = new Intent(intent);
13578
13579        // By default broadcasts do not go to stopped apps.
13580        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13581
13582        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13583            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13584            + " ordered=" + ordered + " userid=" + userId);
13585        if ((resultTo != null) && !ordered) {
13586            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13587        }
13588
13589        userId = handleIncomingUser(callingPid, callingUid, userId,
13590                true, false, "broadcast", callerPackage);
13591
13592        // Make sure that the user who is receiving this broadcast is started.
13593        // If not, we will just skip it.
13594        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13595            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13596                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13597                Slog.w(TAG, "Skipping broadcast of " + intent
13598                        + ": user " + userId + " is stopped");
13599                return ActivityManager.BROADCAST_SUCCESS;
13600            }
13601        }
13602
13603        /*
13604         * Prevent non-system code (defined here to be non-persistent
13605         * processes) from sending protected broadcasts.
13606         */
13607        int callingAppId = UserHandle.getAppId(callingUid);
13608        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13609            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13610            callingUid == 0) {
13611            // Always okay.
13612        } else if (callerApp == null || !callerApp.persistent) {
13613            try {
13614                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13615                        intent.getAction())) {
13616                    String msg = "Permission Denial: not allowed to send broadcast "
13617                            + intent.getAction() + " from pid="
13618                            + callingPid + ", uid=" + callingUid;
13619                    Slog.w(TAG, msg);
13620                    throw new SecurityException(msg);
13621                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13622                    // Special case for compatibility: we don't want apps to send this,
13623                    // but historically it has not been protected and apps may be using it
13624                    // to poke their own app widget.  So, instead of making it protected,
13625                    // just limit it to the caller.
13626                    if (callerApp == null) {
13627                        String msg = "Permission Denial: not allowed to send broadcast "
13628                                + intent.getAction() + " from unknown caller.";
13629                        Slog.w(TAG, msg);
13630                        throw new SecurityException(msg);
13631                    } else if (intent.getComponent() != null) {
13632                        // They are good enough to send to an explicit component...  verify
13633                        // it is being sent to the calling app.
13634                        if (!intent.getComponent().getPackageName().equals(
13635                                callerApp.info.packageName)) {
13636                            String msg = "Permission Denial: not allowed to send broadcast "
13637                                    + intent.getAction() + " to "
13638                                    + intent.getComponent().getPackageName() + " from "
13639                                    + callerApp.info.packageName;
13640                            Slog.w(TAG, msg);
13641                            throw new SecurityException(msg);
13642                        }
13643                    } else {
13644                        // Limit broadcast to their own package.
13645                        intent.setPackage(callerApp.info.packageName);
13646                    }
13647                }
13648            } catch (RemoteException e) {
13649                Slog.w(TAG, "Remote exception", e);
13650                return ActivityManager.BROADCAST_SUCCESS;
13651            }
13652        }
13653
13654        // Handle special intents: if this broadcast is from the package
13655        // manager about a package being removed, we need to remove all of
13656        // its activities from the history stack.
13657        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13658                intent.getAction());
13659        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13660                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13661                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13662                || uidRemoved) {
13663            if (checkComponentPermission(
13664                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13665                    callingPid, callingUid, -1, true)
13666                    == PackageManager.PERMISSION_GRANTED) {
13667                if (uidRemoved) {
13668                    final Bundle intentExtras = intent.getExtras();
13669                    final int uid = intentExtras != null
13670                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13671                    if (uid >= 0) {
13672                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13673                        synchronized (bs) {
13674                            bs.removeUidStatsLocked(uid);
13675                        }
13676                        mAppOpsService.uidRemoved(uid);
13677                    }
13678                } else {
13679                    // If resources are unavailable just force stop all
13680                    // those packages and flush the attribute cache as well.
13681                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13682                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13683                        if (list != null && (list.length > 0)) {
13684                            for (String pkg : list) {
13685                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13686                                        "storage unmount");
13687                            }
13688                            sendPackageBroadcastLocked(
13689                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13690                        }
13691                    } else {
13692                        Uri data = intent.getData();
13693                        String ssp;
13694                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13695                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13696                                    intent.getAction());
13697                            boolean fullUninstall = removed &&
13698                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13699                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13700                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13701                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13702                                        false, fullUninstall, userId,
13703                                        removed ? "pkg removed" : "pkg changed");
13704                            }
13705                            if (removed) {
13706                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13707                                        new String[] {ssp}, userId);
13708                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13709                                    mAppOpsService.packageRemoved(
13710                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13711
13712                                    // Remove all permissions granted from/to this package
13713                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13714                                }
13715                            }
13716                        }
13717                    }
13718                }
13719            } else {
13720                String msg = "Permission Denial: " + intent.getAction()
13721                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13722                        + ", uid=" + callingUid + ")"
13723                        + " requires "
13724                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13725                Slog.w(TAG, msg);
13726                throw new SecurityException(msg);
13727            }
13728
13729        // Special case for adding a package: by default turn on compatibility
13730        // mode.
13731        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13732            Uri data = intent.getData();
13733            String ssp;
13734            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13735                mCompatModePackages.handlePackageAddedLocked(ssp,
13736                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13737            }
13738        }
13739
13740        /*
13741         * If this is the time zone changed action, queue up a message that will reset the timezone
13742         * of all currently running processes. This message will get queued up before the broadcast
13743         * happens.
13744         */
13745        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13746            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13747        }
13748
13749        /*
13750         * If the user set the time, let all running processes know.
13751         */
13752        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13753            final int is24Hour = intent.getBooleanExtra(
13754                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13755            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13756        }
13757
13758        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13759            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13760        }
13761
13762        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13763            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13764            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13765        }
13766
13767        // Add to the sticky list if requested.
13768        if (sticky) {
13769            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13770                    callingPid, callingUid)
13771                    != PackageManager.PERMISSION_GRANTED) {
13772                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13773                        + callingPid + ", uid=" + callingUid
13774                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13775                Slog.w(TAG, msg);
13776                throw new SecurityException(msg);
13777            }
13778            if (requiredPermission != null) {
13779                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13780                        + " and enforce permission " + requiredPermission);
13781                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13782            }
13783            if (intent.getComponent() != null) {
13784                throw new SecurityException(
13785                        "Sticky broadcasts can't target a specific component");
13786            }
13787            // We use userId directly here, since the "all" target is maintained
13788            // as a separate set of sticky broadcasts.
13789            if (userId != UserHandle.USER_ALL) {
13790                // But first, if this is not a broadcast to all users, then
13791                // make sure it doesn't conflict with an existing broadcast to
13792                // all users.
13793                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13794                        UserHandle.USER_ALL);
13795                if (stickies != null) {
13796                    ArrayList<Intent> list = stickies.get(intent.getAction());
13797                    if (list != null) {
13798                        int N = list.size();
13799                        int i;
13800                        for (i=0; i<N; i++) {
13801                            if (intent.filterEquals(list.get(i))) {
13802                                throw new IllegalArgumentException(
13803                                        "Sticky broadcast " + intent + " for user "
13804                                        + userId + " conflicts with existing global broadcast");
13805                            }
13806                        }
13807                    }
13808                }
13809            }
13810            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13811            if (stickies == null) {
13812                stickies = new ArrayMap<String, ArrayList<Intent>>();
13813                mStickyBroadcasts.put(userId, stickies);
13814            }
13815            ArrayList<Intent> list = stickies.get(intent.getAction());
13816            if (list == null) {
13817                list = new ArrayList<Intent>();
13818                stickies.put(intent.getAction(), list);
13819            }
13820            int N = list.size();
13821            int i;
13822            for (i=0; i<N; i++) {
13823                if (intent.filterEquals(list.get(i))) {
13824                    // This sticky already exists, replace it.
13825                    list.set(i, new Intent(intent));
13826                    break;
13827                }
13828            }
13829            if (i >= N) {
13830                list.add(new Intent(intent));
13831            }
13832        }
13833
13834        int[] users;
13835        if (userId == UserHandle.USER_ALL) {
13836            // Caller wants broadcast to go to all started users.
13837            users = mStartedUserArray;
13838        } else {
13839            // Caller wants broadcast to go to one specific user.
13840            users = new int[] {userId};
13841        }
13842
13843        // Figure out who all will receive this broadcast.
13844        List receivers = null;
13845        List<BroadcastFilter> registeredReceivers = null;
13846        // Need to resolve the intent to interested receivers...
13847        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13848                 == 0) {
13849            receivers = collectReceiverComponents(intent, resolvedType, users);
13850        }
13851        if (intent.getComponent() == null) {
13852            registeredReceivers = mReceiverResolver.queryIntent(intent,
13853                    resolvedType, false, userId);
13854        }
13855
13856        final boolean replacePending =
13857                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13858
13859        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13860                + " replacePending=" + replacePending);
13861
13862        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13863        if (!ordered && NR > 0) {
13864            // If we are not serializing this broadcast, then send the
13865            // registered receivers separately so they don't wait for the
13866            // components to be launched.
13867            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13868            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13869                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13870                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13871                    ordered, sticky, false, userId);
13872            if (DEBUG_BROADCAST) Slog.v(
13873                    TAG, "Enqueueing parallel broadcast " + r);
13874            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13875            if (!replaced) {
13876                queue.enqueueParallelBroadcastLocked(r);
13877                queue.scheduleBroadcastsLocked();
13878            }
13879            registeredReceivers = null;
13880            NR = 0;
13881        }
13882
13883        // Merge into one list.
13884        int ir = 0;
13885        if (receivers != null) {
13886            // A special case for PACKAGE_ADDED: do not allow the package
13887            // being added to see this broadcast.  This prevents them from
13888            // using this as a back door to get run as soon as they are
13889            // installed.  Maybe in the future we want to have a special install
13890            // broadcast or such for apps, but we'd like to deliberately make
13891            // this decision.
13892            String skipPackages[] = null;
13893            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13894                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13895                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13896                Uri data = intent.getData();
13897                if (data != null) {
13898                    String pkgName = data.getSchemeSpecificPart();
13899                    if (pkgName != null) {
13900                        skipPackages = new String[] { pkgName };
13901                    }
13902                }
13903            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13904                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13905            }
13906            if (skipPackages != null && (skipPackages.length > 0)) {
13907                for (String skipPackage : skipPackages) {
13908                    if (skipPackage != null) {
13909                        int NT = receivers.size();
13910                        for (int it=0; it<NT; it++) {
13911                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13912                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13913                                receivers.remove(it);
13914                                it--;
13915                                NT--;
13916                            }
13917                        }
13918                    }
13919                }
13920            }
13921
13922            int NT = receivers != null ? receivers.size() : 0;
13923            int it = 0;
13924            ResolveInfo curt = null;
13925            BroadcastFilter curr = null;
13926            while (it < NT && ir < NR) {
13927                if (curt == null) {
13928                    curt = (ResolveInfo)receivers.get(it);
13929                }
13930                if (curr == null) {
13931                    curr = registeredReceivers.get(ir);
13932                }
13933                if (curr.getPriority() >= curt.priority) {
13934                    // Insert this broadcast record into the final list.
13935                    receivers.add(it, curr);
13936                    ir++;
13937                    curr = null;
13938                    it++;
13939                    NT++;
13940                } else {
13941                    // Skip to the next ResolveInfo in the final list.
13942                    it++;
13943                    curt = null;
13944                }
13945            }
13946        }
13947        while (ir < NR) {
13948            if (receivers == null) {
13949                receivers = new ArrayList();
13950            }
13951            receivers.add(registeredReceivers.get(ir));
13952            ir++;
13953        }
13954
13955        if ((receivers != null && receivers.size() > 0)
13956                || resultTo != null) {
13957            BroadcastQueue queue = broadcastQueueForIntent(intent);
13958            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13959                    callerPackage, callingPid, callingUid, resolvedType,
13960                    requiredPermission, appOp, receivers, resultTo, resultCode,
13961                    resultData, map, ordered, sticky, false, userId);
13962            if (DEBUG_BROADCAST) Slog.v(
13963                    TAG, "Enqueueing ordered broadcast " + r
13964                    + ": prev had " + queue.mOrderedBroadcasts.size());
13965            if (DEBUG_BROADCAST) {
13966                int seq = r.intent.getIntExtra("seq", -1);
13967                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13968            }
13969            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13970            if (!replaced) {
13971                queue.enqueueOrderedBroadcastLocked(r);
13972                queue.scheduleBroadcastsLocked();
13973            }
13974        }
13975
13976        return ActivityManager.BROADCAST_SUCCESS;
13977    }
13978
13979    final Intent verifyBroadcastLocked(Intent intent) {
13980        // Refuse possible leaked file descriptors
13981        if (intent != null && intent.hasFileDescriptors() == true) {
13982            throw new IllegalArgumentException("File descriptors passed in Intent");
13983        }
13984
13985        int flags = intent.getFlags();
13986
13987        if (!mProcessesReady) {
13988            // if the caller really truly claims to know what they're doing, go
13989            // ahead and allow the broadcast without launching any receivers
13990            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13991                intent = new Intent(intent);
13992                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13993            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13994                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13995                        + " before boot completion");
13996                throw new IllegalStateException("Cannot broadcast before boot completed");
13997            }
13998        }
13999
14000        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14001            throw new IllegalArgumentException(
14002                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14003        }
14004
14005        return intent;
14006    }
14007
14008    public final int broadcastIntent(IApplicationThread caller,
14009            Intent intent, String resolvedType, IIntentReceiver resultTo,
14010            int resultCode, String resultData, Bundle map,
14011            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14012        enforceNotIsolatedCaller("broadcastIntent");
14013        synchronized(this) {
14014            intent = verifyBroadcastLocked(intent);
14015
14016            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14017            final int callingPid = Binder.getCallingPid();
14018            final int callingUid = Binder.getCallingUid();
14019            final long origId = Binder.clearCallingIdentity();
14020            int res = broadcastIntentLocked(callerApp,
14021                    callerApp != null ? callerApp.info.packageName : null,
14022                    intent, resolvedType, resultTo,
14023                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14024                    callingPid, callingUid, userId);
14025            Binder.restoreCallingIdentity(origId);
14026            return res;
14027        }
14028    }
14029
14030    int broadcastIntentInPackage(String packageName, int uid,
14031            Intent intent, String resolvedType, IIntentReceiver resultTo,
14032            int resultCode, String resultData, Bundle map,
14033            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14034        synchronized(this) {
14035            intent = verifyBroadcastLocked(intent);
14036
14037            final long origId = Binder.clearCallingIdentity();
14038            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14039                    resultTo, resultCode, resultData, map, requiredPermission,
14040                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14041            Binder.restoreCallingIdentity(origId);
14042            return res;
14043        }
14044    }
14045
14046    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14047        // Refuse possible leaked file descriptors
14048        if (intent != null && intent.hasFileDescriptors() == true) {
14049            throw new IllegalArgumentException("File descriptors passed in Intent");
14050        }
14051
14052        userId = handleIncomingUser(Binder.getCallingPid(),
14053                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14054
14055        synchronized(this) {
14056            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14057                    != PackageManager.PERMISSION_GRANTED) {
14058                String msg = "Permission Denial: unbroadcastIntent() from pid="
14059                        + Binder.getCallingPid()
14060                        + ", uid=" + Binder.getCallingUid()
14061                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14062                Slog.w(TAG, msg);
14063                throw new SecurityException(msg);
14064            }
14065            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14066            if (stickies != null) {
14067                ArrayList<Intent> list = stickies.get(intent.getAction());
14068                if (list != null) {
14069                    int N = list.size();
14070                    int i;
14071                    for (i=0; i<N; i++) {
14072                        if (intent.filterEquals(list.get(i))) {
14073                            list.remove(i);
14074                            break;
14075                        }
14076                    }
14077                    if (list.size() <= 0) {
14078                        stickies.remove(intent.getAction());
14079                    }
14080                }
14081                if (stickies.size() <= 0) {
14082                    mStickyBroadcasts.remove(userId);
14083                }
14084            }
14085        }
14086    }
14087
14088    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14089            String resultData, Bundle resultExtras, boolean resultAbort) {
14090        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14091        if (r == null) {
14092            Slog.w(TAG, "finishReceiver called but not found on queue");
14093            return false;
14094        }
14095
14096        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14097    }
14098
14099    void backgroundServicesFinishedLocked(int userId) {
14100        for (BroadcastQueue queue : mBroadcastQueues) {
14101            queue.backgroundServicesFinishedLocked(userId);
14102        }
14103    }
14104
14105    public void finishReceiver(IBinder who, int resultCode, String resultData,
14106            Bundle resultExtras, boolean resultAbort) {
14107        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14108
14109        // Refuse possible leaked file descriptors
14110        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14111            throw new IllegalArgumentException("File descriptors passed in Bundle");
14112        }
14113
14114        final long origId = Binder.clearCallingIdentity();
14115        try {
14116            boolean doNext = false;
14117            BroadcastRecord r;
14118
14119            synchronized(this) {
14120                r = broadcastRecordForReceiverLocked(who);
14121                if (r != null) {
14122                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14123                        resultData, resultExtras, resultAbort, true);
14124                }
14125            }
14126
14127            if (doNext) {
14128                r.queue.processNextBroadcast(false);
14129            }
14130            trimApplications();
14131        } finally {
14132            Binder.restoreCallingIdentity(origId);
14133        }
14134    }
14135
14136    // =========================================================
14137    // INSTRUMENTATION
14138    // =========================================================
14139
14140    public boolean startInstrumentation(ComponentName className,
14141            String profileFile, int flags, Bundle arguments,
14142            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14143            int userId) {
14144        enforceNotIsolatedCaller("startInstrumentation");
14145        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14146                userId, false, true, "startInstrumentation", null);
14147        // Refuse possible leaked file descriptors
14148        if (arguments != null && arguments.hasFileDescriptors()) {
14149            throw new IllegalArgumentException("File descriptors passed in Bundle");
14150        }
14151
14152        synchronized(this) {
14153            InstrumentationInfo ii = null;
14154            ApplicationInfo ai = null;
14155            try {
14156                ii = mContext.getPackageManager().getInstrumentationInfo(
14157                    className, STOCK_PM_FLAGS);
14158                ai = AppGlobals.getPackageManager().getApplicationInfo(
14159                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14160            } catch (PackageManager.NameNotFoundException e) {
14161            } catch (RemoteException e) {
14162            }
14163            if (ii == null) {
14164                reportStartInstrumentationFailure(watcher, className,
14165                        "Unable to find instrumentation info for: " + className);
14166                return false;
14167            }
14168            if (ai == null) {
14169                reportStartInstrumentationFailure(watcher, className,
14170                        "Unable to find instrumentation target package: " + ii.targetPackage);
14171                return false;
14172            }
14173
14174            int match = mContext.getPackageManager().checkSignatures(
14175                    ii.targetPackage, ii.packageName);
14176            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14177                String msg = "Permission Denial: starting instrumentation "
14178                        + className + " from pid="
14179                        + Binder.getCallingPid()
14180                        + ", uid=" + Binder.getCallingPid()
14181                        + " not allowed because package " + ii.packageName
14182                        + " does not have a signature matching the target "
14183                        + ii.targetPackage;
14184                reportStartInstrumentationFailure(watcher, className, msg);
14185                throw new SecurityException(msg);
14186            }
14187
14188            final long origId = Binder.clearCallingIdentity();
14189            // Instrumentation can kill and relaunch even persistent processes
14190            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14191                    "start instr");
14192            ProcessRecord app = addAppLocked(ai, false);
14193            app.instrumentationClass = className;
14194            app.instrumentationInfo = ai;
14195            app.instrumentationProfileFile = profileFile;
14196            app.instrumentationArguments = arguments;
14197            app.instrumentationWatcher = watcher;
14198            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14199            app.instrumentationResultClass = className;
14200            Binder.restoreCallingIdentity(origId);
14201        }
14202
14203        return true;
14204    }
14205
14206    /**
14207     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14208     * error to the logs, but if somebody is watching, send the report there too.  This enables
14209     * the "am" command to report errors with more information.
14210     *
14211     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14212     * @param cn The component name of the instrumentation.
14213     * @param report The error report.
14214     */
14215    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14216            ComponentName cn, String report) {
14217        Slog.w(TAG, report);
14218        try {
14219            if (watcher != null) {
14220                Bundle results = new Bundle();
14221                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14222                results.putString("Error", report);
14223                watcher.instrumentationStatus(cn, -1, results);
14224            }
14225        } catch (RemoteException e) {
14226            Slog.w(TAG, e);
14227        }
14228    }
14229
14230    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14231        if (app.instrumentationWatcher != null) {
14232            try {
14233                // NOTE:  IInstrumentationWatcher *must* be oneway here
14234                app.instrumentationWatcher.instrumentationFinished(
14235                    app.instrumentationClass,
14236                    resultCode,
14237                    results);
14238            } catch (RemoteException e) {
14239            }
14240        }
14241        if (app.instrumentationUiAutomationConnection != null) {
14242            try {
14243                app.instrumentationUiAutomationConnection.shutdown();
14244            } catch (RemoteException re) {
14245                /* ignore */
14246            }
14247            // Only a UiAutomation can set this flag and now that
14248            // it is finished we make sure it is reset to its default.
14249            mUserIsMonkey = false;
14250        }
14251        app.instrumentationWatcher = null;
14252        app.instrumentationUiAutomationConnection = null;
14253        app.instrumentationClass = null;
14254        app.instrumentationInfo = null;
14255        app.instrumentationProfileFile = null;
14256        app.instrumentationArguments = null;
14257
14258        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14259                "finished inst");
14260    }
14261
14262    public void finishInstrumentation(IApplicationThread target,
14263            int resultCode, Bundle results) {
14264        int userId = UserHandle.getCallingUserId();
14265        // Refuse possible leaked file descriptors
14266        if (results != null && results.hasFileDescriptors()) {
14267            throw new IllegalArgumentException("File descriptors passed in Intent");
14268        }
14269
14270        synchronized(this) {
14271            ProcessRecord app = getRecordForAppLocked(target);
14272            if (app == null) {
14273                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14274                return;
14275            }
14276            final long origId = Binder.clearCallingIdentity();
14277            finishInstrumentationLocked(app, resultCode, results);
14278            Binder.restoreCallingIdentity(origId);
14279        }
14280    }
14281
14282    // =========================================================
14283    // CONFIGURATION
14284    // =========================================================
14285
14286    public ConfigurationInfo getDeviceConfigurationInfo() {
14287        ConfigurationInfo config = new ConfigurationInfo();
14288        synchronized (this) {
14289            config.reqTouchScreen = mConfiguration.touchscreen;
14290            config.reqKeyboardType = mConfiguration.keyboard;
14291            config.reqNavigation = mConfiguration.navigation;
14292            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14293                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14294                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14295            }
14296            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14297                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14298                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14299            }
14300            config.reqGlEsVersion = GL_ES_VERSION;
14301        }
14302        return config;
14303    }
14304
14305    ActivityStack getFocusedStack() {
14306        return mStackSupervisor.getFocusedStack();
14307    }
14308
14309    public Configuration getConfiguration() {
14310        Configuration ci;
14311        synchronized(this) {
14312            ci = new Configuration(mConfiguration);
14313        }
14314        return ci;
14315    }
14316
14317    public void updatePersistentConfiguration(Configuration values) {
14318        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14319                "updateConfiguration()");
14320        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14321                "updateConfiguration()");
14322        if (values == null) {
14323            throw new NullPointerException("Configuration must not be null");
14324        }
14325
14326        synchronized(this) {
14327            final long origId = Binder.clearCallingIdentity();
14328            updateConfigurationLocked(values, null, true, false);
14329            Binder.restoreCallingIdentity(origId);
14330        }
14331    }
14332
14333    public void updateConfiguration(Configuration values) {
14334        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14335                "updateConfiguration()");
14336
14337        synchronized(this) {
14338            if (values == null && mWindowManager != null) {
14339                // sentinel: fetch the current configuration from the window manager
14340                values = mWindowManager.computeNewConfiguration();
14341            }
14342
14343            if (mWindowManager != null) {
14344                mProcessList.applyDisplaySize(mWindowManager);
14345            }
14346
14347            final long origId = Binder.clearCallingIdentity();
14348            if (values != null) {
14349                Settings.System.clearConfiguration(values);
14350            }
14351            updateConfigurationLocked(values, null, false, false);
14352            Binder.restoreCallingIdentity(origId);
14353        }
14354    }
14355
14356    /**
14357     * Do either or both things: (1) change the current configuration, and (2)
14358     * make sure the given activity is running with the (now) current
14359     * configuration.  Returns true if the activity has been left running, or
14360     * false if <var>starting</var> is being destroyed to match the new
14361     * configuration.
14362     * @param persistent TODO
14363     */
14364    boolean updateConfigurationLocked(Configuration values,
14365            ActivityRecord starting, boolean persistent, boolean initLocale) {
14366        int changes = 0;
14367
14368        if (values != null) {
14369            Configuration newConfig = new Configuration(mConfiguration);
14370            changes = newConfig.updateFrom(values);
14371            if (changes != 0) {
14372                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14373                    Slog.i(TAG, "Updating configuration to: " + values);
14374                }
14375
14376                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14377
14378                if (values.locale != null && !initLocale) {
14379                    saveLocaleLocked(values.locale,
14380                                     !values.locale.equals(mConfiguration.locale),
14381                                     values.userSetLocale);
14382                }
14383
14384                mConfigurationSeq++;
14385                if (mConfigurationSeq <= 0) {
14386                    mConfigurationSeq = 1;
14387                }
14388                newConfig.seq = mConfigurationSeq;
14389                mConfiguration = newConfig;
14390                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14391
14392                final Configuration configCopy = new Configuration(mConfiguration);
14393
14394                // TODO: If our config changes, should we auto dismiss any currently
14395                // showing dialogs?
14396                mShowDialogs = shouldShowDialogs(newConfig);
14397
14398                AttributeCache ac = AttributeCache.instance();
14399                if (ac != null) {
14400                    ac.updateConfiguration(configCopy);
14401                }
14402
14403                // Make sure all resources in our process are updated
14404                // right now, so that anyone who is going to retrieve
14405                // resource values after we return will be sure to get
14406                // the new ones.  This is especially important during
14407                // boot, where the first config change needs to guarantee
14408                // all resources have that config before following boot
14409                // code is executed.
14410                mSystemThread.applyConfigurationToResources(configCopy);
14411
14412                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14413                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14414                    msg.obj = new Configuration(configCopy);
14415                    mHandler.sendMessage(msg);
14416                }
14417
14418                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14419                    ProcessRecord app = mLruProcesses.get(i);
14420                    try {
14421                        if (app.thread != null) {
14422                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14423                                    + app.processName + " new config " + mConfiguration);
14424                            app.thread.scheduleConfigurationChanged(configCopy);
14425                        }
14426                    } catch (Exception e) {
14427                    }
14428                }
14429                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14430                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14431                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14432                        | Intent.FLAG_RECEIVER_FOREGROUND);
14433                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14434                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14435                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14436                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14437                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14438                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14439                    broadcastIntentLocked(null, null, intent,
14440                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14441                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14442                }
14443            }
14444        }
14445
14446        boolean kept = true;
14447        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14448        // mainStack is null during startup.
14449        if (mainStack != null) {
14450            if (changes != 0 && starting == null) {
14451                // If the configuration changed, and the caller is not already
14452                // in the process of starting an activity, then find the top
14453                // activity to check if its configuration needs to change.
14454                starting = mainStack.topRunningActivityLocked(null);
14455            }
14456
14457            if (starting != null) {
14458                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14459                // And we need to make sure at this point that all other activities
14460                // are made visible with the correct configuration.
14461                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14462            }
14463        }
14464
14465        if (values != null && mWindowManager != null) {
14466            mWindowManager.setNewConfiguration(mConfiguration);
14467        }
14468
14469        return kept;
14470    }
14471
14472    /**
14473     * Decide based on the configuration whether we should shouw the ANR,
14474     * crash, etc dialogs.  The idea is that if there is no affordnace to
14475     * press the on-screen buttons, we shouldn't show the dialog.
14476     *
14477     * A thought: SystemUI might also want to get told about this, the Power
14478     * dialog / global actions also might want different behaviors.
14479     */
14480    private static final boolean shouldShowDialogs(Configuration config) {
14481        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14482                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14483    }
14484
14485    /**
14486     * Save the locale.  You must be inside a synchronized (this) block.
14487     */
14488    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14489        if(isDiff) {
14490            SystemProperties.set("user.language", l.getLanguage());
14491            SystemProperties.set("user.region", l.getCountry());
14492        }
14493
14494        if(isPersist) {
14495            SystemProperties.set("persist.sys.language", l.getLanguage());
14496            SystemProperties.set("persist.sys.country", l.getCountry());
14497            SystemProperties.set("persist.sys.localevar", l.getVariant());
14498        }
14499    }
14500
14501    @Override
14502    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14503        ActivityRecord srec = ActivityRecord.forToken(token);
14504        return srec != null && srec.task.affinity != null &&
14505                srec.task.affinity.equals(destAffinity);
14506    }
14507
14508    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14509            Intent resultData) {
14510
14511        synchronized (this) {
14512            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14513            if (stack != null) {
14514                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14515            }
14516            return false;
14517        }
14518    }
14519
14520    public int getLaunchedFromUid(IBinder activityToken) {
14521        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14522        if (srec == null) {
14523            return -1;
14524        }
14525        return srec.launchedFromUid;
14526    }
14527
14528    public String getLaunchedFromPackage(IBinder activityToken) {
14529        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14530        if (srec == null) {
14531            return null;
14532        }
14533        return srec.launchedFromPackage;
14534    }
14535
14536    // =========================================================
14537    // LIFETIME MANAGEMENT
14538    // =========================================================
14539
14540    // Returns which broadcast queue the app is the current [or imminent] receiver
14541    // on, or 'null' if the app is not an active broadcast recipient.
14542    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14543        BroadcastRecord r = app.curReceiver;
14544        if (r != null) {
14545            return r.queue;
14546        }
14547
14548        // It's not the current receiver, but it might be starting up to become one
14549        synchronized (this) {
14550            for (BroadcastQueue queue : mBroadcastQueues) {
14551                r = queue.mPendingBroadcast;
14552                if (r != null && r.curApp == app) {
14553                    // found it; report which queue it's in
14554                    return queue;
14555                }
14556            }
14557        }
14558
14559        return null;
14560    }
14561
14562    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14563            boolean doingAll, long now) {
14564        if (mAdjSeq == app.adjSeq) {
14565            // This adjustment has already been computed.
14566            return app.curRawAdj;
14567        }
14568
14569        if (app.thread == null) {
14570            app.adjSeq = mAdjSeq;
14571            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14572            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14573            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14574        }
14575
14576        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14577        app.adjSource = null;
14578        app.adjTarget = null;
14579        app.empty = false;
14580        app.cached = false;
14581
14582        final int activitiesSize = app.activities.size();
14583
14584        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14585            // The max adjustment doesn't allow this app to be anything
14586            // below foreground, so it is not worth doing work for it.
14587            app.adjType = "fixed";
14588            app.adjSeq = mAdjSeq;
14589            app.curRawAdj = app.maxAdj;
14590            app.foregroundActivities = false;
14591            app.keeping = true;
14592            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14593            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14594            // System processes can do UI, and when they do we want to have
14595            // them trim their memory after the user leaves the UI.  To
14596            // facilitate this, here we need to determine whether or not it
14597            // is currently showing UI.
14598            app.systemNoUi = true;
14599            if (app == TOP_APP) {
14600                app.systemNoUi = false;
14601            } else if (activitiesSize > 0) {
14602                for (int j = 0; j < activitiesSize; j++) {
14603                    final ActivityRecord r = app.activities.get(j);
14604                    if (r.visible) {
14605                        app.systemNoUi = false;
14606                    }
14607                }
14608            }
14609            if (!app.systemNoUi) {
14610                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14611            }
14612            return (app.curAdj=app.maxAdj);
14613        }
14614
14615        app.keeping = false;
14616        app.systemNoUi = false;
14617
14618        // Determine the importance of the process, starting with most
14619        // important to least, and assign an appropriate OOM adjustment.
14620        int adj;
14621        int schedGroup;
14622        int procState;
14623        boolean foregroundActivities = false;
14624        boolean interesting = false;
14625        BroadcastQueue queue;
14626        if (app == TOP_APP) {
14627            // The last app on the list is the foreground app.
14628            adj = ProcessList.FOREGROUND_APP_ADJ;
14629            schedGroup = Process.THREAD_GROUP_DEFAULT;
14630            app.adjType = "top-activity";
14631            foregroundActivities = true;
14632            interesting = true;
14633            procState = ActivityManager.PROCESS_STATE_TOP;
14634        } else if (app.instrumentationClass != null) {
14635            // Don't want to kill running instrumentation.
14636            adj = ProcessList.FOREGROUND_APP_ADJ;
14637            schedGroup = Process.THREAD_GROUP_DEFAULT;
14638            app.adjType = "instrumentation";
14639            interesting = true;
14640            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14641        } else if ((queue = isReceivingBroadcast(app)) != null) {
14642            // An app that is currently receiving a broadcast also
14643            // counts as being in the foreground for OOM killer purposes.
14644            // It's placed in a sched group based on the nature of the
14645            // broadcast as reflected by which queue it's active in.
14646            adj = ProcessList.FOREGROUND_APP_ADJ;
14647            schedGroup = (queue == mFgBroadcastQueue)
14648                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14649            app.adjType = "broadcast";
14650            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14651        } else if (app.executingServices.size() > 0) {
14652            // An app that is currently executing a service callback also
14653            // counts as being in the foreground.
14654            adj = ProcessList.FOREGROUND_APP_ADJ;
14655            schedGroup = app.execServicesFg ?
14656                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14657            app.adjType = "exec-service";
14658            procState = ActivityManager.PROCESS_STATE_SERVICE;
14659            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14660        } else {
14661            // As far as we know the process is empty.  We may change our mind later.
14662            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14663            // At this point we don't actually know the adjustment.  Use the cached adj
14664            // value that the caller wants us to.
14665            adj = cachedAdj;
14666            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14667            app.cached = true;
14668            app.empty = true;
14669            app.adjType = "cch-empty";
14670        }
14671
14672        // Examine all activities if not already foreground.
14673        if (!foregroundActivities && activitiesSize > 0) {
14674            for (int j = 0; j < activitiesSize; j++) {
14675                final ActivityRecord r = app.activities.get(j);
14676                if (r.app != app) {
14677                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14678                            + app + "?!?");
14679                    continue;
14680                }
14681                if (r.visible) {
14682                    // App has a visible activity; only upgrade adjustment.
14683                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14684                        adj = ProcessList.VISIBLE_APP_ADJ;
14685                        app.adjType = "visible";
14686                    }
14687                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14688                        procState = ActivityManager.PROCESS_STATE_TOP;
14689                    }
14690                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14691                    app.cached = false;
14692                    app.empty = false;
14693                    foregroundActivities = true;
14694                    break;
14695                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14696                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14697                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14698                        app.adjType = "pausing";
14699                    }
14700                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14701                        procState = ActivityManager.PROCESS_STATE_TOP;
14702                    }
14703                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14704                    app.cached = false;
14705                    app.empty = false;
14706                    foregroundActivities = true;
14707                } else if (r.state == ActivityState.STOPPING) {
14708                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14709                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14710                        app.adjType = "stopping";
14711                    }
14712                    // For the process state, we will at this point consider the
14713                    // process to be cached.  It will be cached either as an activity
14714                    // or empty depending on whether the activity is finishing.  We do
14715                    // this so that we can treat the process as cached for purposes of
14716                    // memory trimming (determing current memory level, trim command to
14717                    // send to process) since there can be an arbitrary number of stopping
14718                    // processes and they should soon all go into the cached state.
14719                    if (!r.finishing) {
14720                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14721                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14722                        }
14723                    }
14724                    app.cached = false;
14725                    app.empty = false;
14726                    foregroundActivities = true;
14727                } else {
14728                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14729                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14730                        app.adjType = "cch-act";
14731                    }
14732                }
14733            }
14734        }
14735
14736        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14737            if (app.foregroundServices) {
14738                // The user is aware of this app, so make it visible.
14739                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14740                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14741                app.cached = false;
14742                app.adjType = "fg-service";
14743                schedGroup = Process.THREAD_GROUP_DEFAULT;
14744            } else if (app.forcingToForeground != null) {
14745                // The user is aware of this app, so make it visible.
14746                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14747                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14748                app.cached = false;
14749                app.adjType = "force-fg";
14750                app.adjSource = app.forcingToForeground;
14751                schedGroup = Process.THREAD_GROUP_DEFAULT;
14752            }
14753        }
14754
14755        if (app.foregroundServices) {
14756            interesting = true;
14757        }
14758
14759        if (app == mHeavyWeightProcess) {
14760            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14761                // We don't want to kill the current heavy-weight process.
14762                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14763                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14764                app.cached = false;
14765                app.adjType = "heavy";
14766            }
14767            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14768                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14769            }
14770        }
14771
14772        if (app == mHomeProcess) {
14773            if (adj > ProcessList.HOME_APP_ADJ) {
14774                // This process is hosting what we currently consider to be the
14775                // home app, so we don't want to let it go into the background.
14776                adj = ProcessList.HOME_APP_ADJ;
14777                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14778                app.cached = false;
14779                app.adjType = "home";
14780            }
14781            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14782                procState = ActivityManager.PROCESS_STATE_HOME;
14783            }
14784        }
14785
14786        if (app == mPreviousProcess && app.activities.size() > 0) {
14787            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14788                // This was the previous process that showed UI to the user.
14789                // We want to try to keep it around more aggressively, to give
14790                // a good experience around switching between two apps.
14791                adj = ProcessList.PREVIOUS_APP_ADJ;
14792                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14793                app.cached = false;
14794                app.adjType = "previous";
14795            }
14796            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14797                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14798            }
14799        }
14800
14801        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14802                + " reason=" + app.adjType);
14803
14804        // By default, we use the computed adjustment.  It may be changed if
14805        // there are applications dependent on our services or providers, but
14806        // this gives us a baseline and makes sure we don't get into an
14807        // infinite recursion.
14808        app.adjSeq = mAdjSeq;
14809        app.curRawAdj = adj;
14810        app.hasStartedServices = false;
14811
14812        if (mBackupTarget != null && app == mBackupTarget.app) {
14813            // If possible we want to avoid killing apps while they're being backed up
14814            if (adj > ProcessList.BACKUP_APP_ADJ) {
14815                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14816                adj = ProcessList.BACKUP_APP_ADJ;
14817                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14818                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14819                }
14820                app.adjType = "backup";
14821                app.cached = false;
14822            }
14823            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14824                procState = ActivityManager.PROCESS_STATE_BACKUP;
14825            }
14826        }
14827
14828        boolean mayBeTop = false;
14829
14830        for (int is = app.services.size()-1;
14831                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14832                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14833                        || procState > ActivityManager.PROCESS_STATE_TOP);
14834                is--) {
14835            ServiceRecord s = app.services.valueAt(is);
14836            if (s.startRequested) {
14837                app.hasStartedServices = true;
14838                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14839                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14840                }
14841                if (app.hasShownUi && app != mHomeProcess) {
14842                    // If this process has shown some UI, let it immediately
14843                    // go to the LRU list because it may be pretty heavy with
14844                    // UI stuff.  We'll tag it with a label just to help
14845                    // debug and understand what is going on.
14846                    if (adj > ProcessList.SERVICE_ADJ) {
14847                        app.adjType = "cch-started-ui-services";
14848                    }
14849                } else {
14850                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14851                        // This service has seen some activity within
14852                        // recent memory, so we will keep its process ahead
14853                        // of the background processes.
14854                        if (adj > ProcessList.SERVICE_ADJ) {
14855                            adj = ProcessList.SERVICE_ADJ;
14856                            app.adjType = "started-services";
14857                            app.cached = false;
14858                        }
14859                    }
14860                    // If we have let the service slide into the background
14861                    // state, still have some text describing what it is doing
14862                    // even though the service no longer has an impact.
14863                    if (adj > ProcessList.SERVICE_ADJ) {
14864                        app.adjType = "cch-started-services";
14865                    }
14866                }
14867                // Don't kill this process because it is doing work; it
14868                // has said it is doing work.
14869                app.keeping = true;
14870            }
14871            for (int conni = s.connections.size()-1;
14872                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14873                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14874                            || procState > ActivityManager.PROCESS_STATE_TOP);
14875                    conni--) {
14876                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14877                for (int i = 0;
14878                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14879                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14880                                || procState > ActivityManager.PROCESS_STATE_TOP);
14881                        i++) {
14882                    // XXX should compute this based on the max of
14883                    // all connected clients.
14884                    ConnectionRecord cr = clist.get(i);
14885                    if (cr.binding.client == app) {
14886                        // Binding to ourself is not interesting.
14887                        continue;
14888                    }
14889                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14890                        ProcessRecord client = cr.binding.client;
14891                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14892                                TOP_APP, doingAll, now);
14893                        int clientProcState = client.curProcState;
14894                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14895                            // If the other app is cached for any reason, for purposes here
14896                            // we are going to consider it empty.  The specific cached state
14897                            // doesn't propagate except under certain conditions.
14898                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14899                        }
14900                        String adjType = null;
14901                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14902                            // Not doing bind OOM management, so treat
14903                            // this guy more like a started service.
14904                            if (app.hasShownUi && app != mHomeProcess) {
14905                                // If this process has shown some UI, let it immediately
14906                                // go to the LRU list because it may be pretty heavy with
14907                                // UI stuff.  We'll tag it with a label just to help
14908                                // debug and understand what is going on.
14909                                if (adj > clientAdj) {
14910                                    adjType = "cch-bound-ui-services";
14911                                }
14912                                app.cached = false;
14913                                clientAdj = adj;
14914                                clientProcState = procState;
14915                            } else {
14916                                if (now >= (s.lastActivity
14917                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14918                                    // This service has not seen activity within
14919                                    // recent memory, so allow it to drop to the
14920                                    // LRU list if there is no other reason to keep
14921                                    // it around.  We'll also tag it with a label just
14922                                    // to help debug and undertand what is going on.
14923                                    if (adj > clientAdj) {
14924                                        adjType = "cch-bound-services";
14925                                    }
14926                                    clientAdj = adj;
14927                                }
14928                            }
14929                        }
14930                        if (adj > clientAdj) {
14931                            // If this process has recently shown UI, and
14932                            // the process that is binding to it is less
14933                            // important than being visible, then we don't
14934                            // care about the binding as much as we care
14935                            // about letting this process get into the LRU
14936                            // list to be killed and restarted if needed for
14937                            // memory.
14938                            if (app.hasShownUi && app != mHomeProcess
14939                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14940                                adjType = "cch-bound-ui-services";
14941                            } else {
14942                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14943                                        |Context.BIND_IMPORTANT)) != 0) {
14944                                    adj = clientAdj;
14945                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14946                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14947                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14948                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14949                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14950                                    adj = clientAdj;
14951                                } else {
14952                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14953                                        adj = ProcessList.VISIBLE_APP_ADJ;
14954                                    }
14955                                }
14956                                if (!client.cached) {
14957                                    app.cached = false;
14958                                }
14959                                if (client.keeping) {
14960                                    app.keeping = true;
14961                                }
14962                                adjType = "service";
14963                            }
14964                        }
14965                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14966                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14967                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14968                            }
14969                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14970                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14971                                    // Special handling of clients who are in the top state.
14972                                    // We *may* want to consider this process to be in the
14973                                    // top state as well, but only if there is not another
14974                                    // reason for it to be running.  Being on the top is a
14975                                    // special state, meaning you are specifically running
14976                                    // for the current top app.  If the process is already
14977                                    // running in the background for some other reason, it
14978                                    // is more important to continue considering it to be
14979                                    // in the background state.
14980                                    mayBeTop = true;
14981                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14982                                } else {
14983                                    // Special handling for above-top states (persistent
14984                                    // processes).  These should not bring the current process
14985                                    // into the top state, since they are not on top.  Instead
14986                                    // give them the best state after that.
14987                                    clientProcState =
14988                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14989                                }
14990                            }
14991                        } else {
14992                            if (clientProcState <
14993                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14994                                clientProcState =
14995                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14996                            }
14997                        }
14998                        if (procState > clientProcState) {
14999                            procState = clientProcState;
15000                        }
15001                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15002                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15003                            app.pendingUiClean = true;
15004                        }
15005                        if (adjType != null) {
15006                            app.adjType = adjType;
15007                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15008                                    .REASON_SERVICE_IN_USE;
15009                            app.adjSource = cr.binding.client;
15010                            app.adjSourceOom = clientAdj;
15011                            app.adjTarget = s.name;
15012                        }
15013                    }
15014                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15015                        app.treatLikeActivity = true;
15016                    }
15017                    final ActivityRecord a = cr.activity;
15018                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15019                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15020                                (a.visible || a.state == ActivityState.RESUMED
15021                                 || a.state == ActivityState.PAUSING)) {
15022                            adj = ProcessList.FOREGROUND_APP_ADJ;
15023                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15024                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15025                            }
15026                            app.cached = false;
15027                            app.adjType = "service";
15028                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15029                                    .REASON_SERVICE_IN_USE;
15030                            app.adjSource = a;
15031                            app.adjSourceOom = adj;
15032                            app.adjTarget = s.name;
15033                        }
15034                    }
15035                }
15036            }
15037        }
15038
15039        for (int provi = app.pubProviders.size()-1;
15040                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15041                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15042                        || procState > ActivityManager.PROCESS_STATE_TOP);
15043                provi--) {
15044            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15045            for (int i = cpr.connections.size()-1;
15046                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15047                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15048                            || procState > ActivityManager.PROCESS_STATE_TOP);
15049                    i--) {
15050                ContentProviderConnection conn = cpr.connections.get(i);
15051                ProcessRecord client = conn.client;
15052                if (client == app) {
15053                    // Being our own client is not interesting.
15054                    continue;
15055                }
15056                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15057                int clientProcState = client.curProcState;
15058                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15059                    // If the other app is cached for any reason, for purposes here
15060                    // we are going to consider it empty.
15061                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15062                }
15063                if (adj > clientAdj) {
15064                    if (app.hasShownUi && app != mHomeProcess
15065                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15066                        app.adjType = "cch-ui-provider";
15067                    } else {
15068                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15069                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15070                        app.adjType = "provider";
15071                    }
15072                    app.cached &= client.cached;
15073                    app.keeping |= client.keeping;
15074                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15075                            .REASON_PROVIDER_IN_USE;
15076                    app.adjSource = client;
15077                    app.adjSourceOom = clientAdj;
15078                    app.adjTarget = cpr.name;
15079                }
15080                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15081                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15082                        // Special handling of clients who are in the top state.
15083                        // We *may* want to consider this process to be in the
15084                        // top state as well, but only if there is not another
15085                        // reason for it to be running.  Being on the top is a
15086                        // special state, meaning you are specifically running
15087                        // for the current top app.  If the process is already
15088                        // running in the background for some other reason, it
15089                        // is more important to continue considering it to be
15090                        // in the background state.
15091                        mayBeTop = true;
15092                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15093                    } else {
15094                        // Special handling for above-top states (persistent
15095                        // processes).  These should not bring the current process
15096                        // into the top state, since they are not on top.  Instead
15097                        // give them the best state after that.
15098                        clientProcState =
15099                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15100                    }
15101                }
15102                if (procState > clientProcState) {
15103                    procState = clientProcState;
15104                }
15105                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15106                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15107                }
15108            }
15109            // If the provider has external (non-framework) process
15110            // dependencies, ensure that its adjustment is at least
15111            // FOREGROUND_APP_ADJ.
15112            if (cpr.hasExternalProcessHandles()) {
15113                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15114                    adj = ProcessList.FOREGROUND_APP_ADJ;
15115                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15116                    app.cached = false;
15117                    app.keeping = true;
15118                    app.adjType = "provider";
15119                    app.adjTarget = cpr.name;
15120                }
15121                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15122                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15123                }
15124            }
15125        }
15126
15127        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15128            // A client of one of our services or providers is in the top state.  We
15129            // *may* want to be in the top state, but not if we are already running in
15130            // the background for some other reason.  For the decision here, we are going
15131            // to pick out a few specific states that we want to remain in when a client
15132            // is top (states that tend to be longer-term) and otherwise allow it to go
15133            // to the top state.
15134            switch (procState) {
15135                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15136                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15137                case ActivityManager.PROCESS_STATE_SERVICE:
15138                    // These all are longer-term states, so pull them up to the top
15139                    // of the background states, but not all the way to the top state.
15140                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15141                    break;
15142                default:
15143                    // Otherwise, top is a better choice, so take it.
15144                    procState = ActivityManager.PROCESS_STATE_TOP;
15145                    break;
15146            }
15147        }
15148
15149        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15150            if (app.hasClientActivities) {
15151                // This is a cached process, but with client activities.  Mark it so.
15152                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15153                app.adjType = "cch-client-act";
15154            } else if (app.treatLikeActivity) {
15155                // This is a cached process, but somebody wants us to treat it like it has
15156                // an activity, okay!
15157                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15158                app.adjType = "cch-as-act";
15159            }
15160        }
15161
15162        if (adj == ProcessList.SERVICE_ADJ) {
15163            if (doingAll) {
15164                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15165                mNewNumServiceProcs++;
15166                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15167                if (!app.serviceb) {
15168                    // This service isn't far enough down on the LRU list to
15169                    // normally be a B service, but if we are low on RAM and it
15170                    // is large we want to force it down since we would prefer to
15171                    // keep launcher over it.
15172                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15173                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15174                        app.serviceHighRam = true;
15175                        app.serviceb = true;
15176                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15177                    } else {
15178                        mNewNumAServiceProcs++;
15179                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15180                    }
15181                } else {
15182                    app.serviceHighRam = false;
15183                }
15184            }
15185            if (app.serviceb) {
15186                adj = ProcessList.SERVICE_B_ADJ;
15187            }
15188        }
15189
15190        app.curRawAdj = adj;
15191
15192        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15193        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15194        if (adj > app.maxAdj) {
15195            adj = app.maxAdj;
15196            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15197                schedGroup = Process.THREAD_GROUP_DEFAULT;
15198            }
15199        }
15200        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15201            app.keeping = true;
15202        }
15203
15204        // Do final modification to adj.  Everything we do between here and applying
15205        // the final setAdj must be done in this function, because we will also use
15206        // it when computing the final cached adj later.  Note that we don't need to
15207        // worry about this for max adj above, since max adj will always be used to
15208        // keep it out of the cached vaues.
15209        app.curAdj = app.modifyRawOomAdj(adj);
15210        app.curSchedGroup = schedGroup;
15211        app.curProcState = procState;
15212        app.foregroundActivities = foregroundActivities;
15213
15214        return app.curRawAdj;
15215    }
15216
15217    /**
15218     * Schedule PSS collection of a process.
15219     */
15220    void requestPssLocked(ProcessRecord proc, int procState) {
15221        if (mPendingPssProcesses.contains(proc)) {
15222            return;
15223        }
15224        if (mPendingPssProcesses.size() == 0) {
15225            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15226        }
15227        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15228        proc.pssProcState = procState;
15229        mPendingPssProcesses.add(proc);
15230    }
15231
15232    /**
15233     * Schedule PSS collection of all processes.
15234     */
15235    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15236        if (!always) {
15237            if (now < (mLastFullPssTime +
15238                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15239                return;
15240            }
15241        }
15242        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15243        mLastFullPssTime = now;
15244        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15245        mPendingPssProcesses.clear();
15246        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15247            ProcessRecord app = mLruProcesses.get(i);
15248            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15249                app.pssProcState = app.setProcState;
15250                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15251                        isSleeping(), now);
15252                mPendingPssProcesses.add(app);
15253            }
15254        }
15255        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15256    }
15257
15258    /**
15259     * Ask a given process to GC right now.
15260     */
15261    final void performAppGcLocked(ProcessRecord app) {
15262        try {
15263            app.lastRequestedGc = SystemClock.uptimeMillis();
15264            if (app.thread != null) {
15265                if (app.reportLowMemory) {
15266                    app.reportLowMemory = false;
15267                    app.thread.scheduleLowMemory();
15268                } else {
15269                    app.thread.processInBackground();
15270                }
15271            }
15272        } catch (Exception e) {
15273            // whatever.
15274        }
15275    }
15276
15277    /**
15278     * Returns true if things are idle enough to perform GCs.
15279     */
15280    private final boolean canGcNowLocked() {
15281        boolean processingBroadcasts = false;
15282        for (BroadcastQueue q : mBroadcastQueues) {
15283            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15284                processingBroadcasts = true;
15285            }
15286        }
15287        return !processingBroadcasts
15288                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15289    }
15290
15291    /**
15292     * Perform GCs on all processes that are waiting for it, but only
15293     * if things are idle.
15294     */
15295    final void performAppGcsLocked() {
15296        final int N = mProcessesToGc.size();
15297        if (N <= 0) {
15298            return;
15299        }
15300        if (canGcNowLocked()) {
15301            while (mProcessesToGc.size() > 0) {
15302                ProcessRecord proc = mProcessesToGc.remove(0);
15303                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15304                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15305                            <= SystemClock.uptimeMillis()) {
15306                        // To avoid spamming the system, we will GC processes one
15307                        // at a time, waiting a few seconds between each.
15308                        performAppGcLocked(proc);
15309                        scheduleAppGcsLocked();
15310                        return;
15311                    } else {
15312                        // It hasn't been long enough since we last GCed this
15313                        // process...  put it in the list to wait for its time.
15314                        addProcessToGcListLocked(proc);
15315                        break;
15316                    }
15317                }
15318            }
15319
15320            scheduleAppGcsLocked();
15321        }
15322    }
15323
15324    /**
15325     * If all looks good, perform GCs on all processes waiting for them.
15326     */
15327    final void performAppGcsIfAppropriateLocked() {
15328        if (canGcNowLocked()) {
15329            performAppGcsLocked();
15330            return;
15331        }
15332        // Still not idle, wait some more.
15333        scheduleAppGcsLocked();
15334    }
15335
15336    /**
15337     * Schedule the execution of all pending app GCs.
15338     */
15339    final void scheduleAppGcsLocked() {
15340        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15341
15342        if (mProcessesToGc.size() > 0) {
15343            // Schedule a GC for the time to the next process.
15344            ProcessRecord proc = mProcessesToGc.get(0);
15345            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15346
15347            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15348            long now = SystemClock.uptimeMillis();
15349            if (when < (now+GC_TIMEOUT)) {
15350                when = now + GC_TIMEOUT;
15351            }
15352            mHandler.sendMessageAtTime(msg, when);
15353        }
15354    }
15355
15356    /**
15357     * Add a process to the array of processes waiting to be GCed.  Keeps the
15358     * list in sorted order by the last GC time.  The process can't already be
15359     * on the list.
15360     */
15361    final void addProcessToGcListLocked(ProcessRecord proc) {
15362        boolean added = false;
15363        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15364            if (mProcessesToGc.get(i).lastRequestedGc <
15365                    proc.lastRequestedGc) {
15366                added = true;
15367                mProcessesToGc.add(i+1, proc);
15368                break;
15369            }
15370        }
15371        if (!added) {
15372            mProcessesToGc.add(0, proc);
15373        }
15374    }
15375
15376    /**
15377     * Set up to ask a process to GC itself.  This will either do it
15378     * immediately, or put it on the list of processes to gc the next
15379     * time things are idle.
15380     */
15381    final void scheduleAppGcLocked(ProcessRecord app) {
15382        long now = SystemClock.uptimeMillis();
15383        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15384            return;
15385        }
15386        if (!mProcessesToGc.contains(app)) {
15387            addProcessToGcListLocked(app);
15388            scheduleAppGcsLocked();
15389        }
15390    }
15391
15392    final void checkExcessivePowerUsageLocked(boolean doKills) {
15393        updateCpuStatsNow();
15394
15395        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15396        boolean doWakeKills = doKills;
15397        boolean doCpuKills = doKills;
15398        if (mLastPowerCheckRealtime == 0) {
15399            doWakeKills = false;
15400        }
15401        if (mLastPowerCheckUptime == 0) {
15402            doCpuKills = false;
15403        }
15404        if (stats.isScreenOn()) {
15405            doWakeKills = false;
15406        }
15407        final long curRealtime = SystemClock.elapsedRealtime();
15408        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15409        final long curUptime = SystemClock.uptimeMillis();
15410        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15411        mLastPowerCheckRealtime = curRealtime;
15412        mLastPowerCheckUptime = curUptime;
15413        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15414            doWakeKills = false;
15415        }
15416        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15417            doCpuKills = false;
15418        }
15419        int i = mLruProcesses.size();
15420        while (i > 0) {
15421            i--;
15422            ProcessRecord app = mLruProcesses.get(i);
15423            if (!app.keeping) {
15424                long wtime;
15425                synchronized (stats) {
15426                    wtime = stats.getProcessWakeTime(app.info.uid,
15427                            app.pid, curRealtime);
15428                }
15429                long wtimeUsed = wtime - app.lastWakeTime;
15430                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15431                if (DEBUG_POWER) {
15432                    StringBuilder sb = new StringBuilder(128);
15433                    sb.append("Wake for ");
15434                    app.toShortString(sb);
15435                    sb.append(": over ");
15436                    TimeUtils.formatDuration(realtimeSince, sb);
15437                    sb.append(" used ");
15438                    TimeUtils.formatDuration(wtimeUsed, sb);
15439                    sb.append(" (");
15440                    sb.append((wtimeUsed*100)/realtimeSince);
15441                    sb.append("%)");
15442                    Slog.i(TAG, sb.toString());
15443                    sb.setLength(0);
15444                    sb.append("CPU for ");
15445                    app.toShortString(sb);
15446                    sb.append(": over ");
15447                    TimeUtils.formatDuration(uptimeSince, sb);
15448                    sb.append(" used ");
15449                    TimeUtils.formatDuration(cputimeUsed, sb);
15450                    sb.append(" (");
15451                    sb.append((cputimeUsed*100)/uptimeSince);
15452                    sb.append("%)");
15453                    Slog.i(TAG, sb.toString());
15454                }
15455                // If a process has held a wake lock for more
15456                // than 50% of the time during this period,
15457                // that sounds bad.  Kill!
15458                if (doWakeKills && realtimeSince > 0
15459                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15460                    synchronized (stats) {
15461                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15462                                realtimeSince, wtimeUsed);
15463                    }
15464                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15465                            + " during " + realtimeSince);
15466                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15467                } else if (doCpuKills && uptimeSince > 0
15468                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15469                    synchronized (stats) {
15470                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15471                                uptimeSince, cputimeUsed);
15472                    }
15473                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15474                            + " during " + uptimeSince);
15475                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15476                } else {
15477                    app.lastWakeTime = wtime;
15478                    app.lastCpuTime = app.curCpuTime;
15479                }
15480            }
15481        }
15482    }
15483
15484    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15485            ProcessRecord TOP_APP, boolean doingAll, long now) {
15486        boolean success = true;
15487
15488        if (app.curRawAdj != app.setRawAdj) {
15489            if (wasKeeping && !app.keeping) {
15490                // This app is no longer something we want to keep.  Note
15491                // its current wake lock time to later know to kill it if
15492                // it is not behaving well.
15493                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15494                synchronized (stats) {
15495                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15496                            app.pid, SystemClock.elapsedRealtime());
15497                }
15498                app.lastCpuTime = app.curCpuTime;
15499            }
15500
15501            app.setRawAdj = app.curRawAdj;
15502        }
15503
15504        int changes = 0;
15505
15506        if (app.curAdj != app.setAdj) {
15507            ProcessList.setOomAdj(app.pid, app.curAdj);
15508            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15509                TAG, "Set " + app.pid + " " + app.processName +
15510                " adj " + app.curAdj + ": " + app.adjType);
15511            app.setAdj = app.curAdj;
15512        }
15513
15514        if (app.setSchedGroup != app.curSchedGroup) {
15515            app.setSchedGroup = app.curSchedGroup;
15516            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15517                    "Setting process group of " + app.processName
15518                    + " to " + app.curSchedGroup);
15519            if (app.waitingToKill != null &&
15520                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15521                killUnneededProcessLocked(app, app.waitingToKill);
15522                success = false;
15523            } else {
15524                if (true) {
15525                    long oldId = Binder.clearCallingIdentity();
15526                    try {
15527                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15528                    } catch (Exception e) {
15529                        Slog.w(TAG, "Failed setting process group of " + app.pid
15530                                + " to " + app.curSchedGroup);
15531                        e.printStackTrace();
15532                    } finally {
15533                        Binder.restoreCallingIdentity(oldId);
15534                    }
15535                } else {
15536                    if (app.thread != null) {
15537                        try {
15538                            app.thread.setSchedulingGroup(app.curSchedGroup);
15539                        } catch (RemoteException e) {
15540                        }
15541                    }
15542                }
15543                Process.setSwappiness(app.pid,
15544                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15545            }
15546        }
15547        if (app.repForegroundActivities != app.foregroundActivities) {
15548            app.repForegroundActivities = app.foregroundActivities;
15549            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15550        }
15551        if (app.repProcState != app.curProcState) {
15552            app.repProcState = app.curProcState;
15553            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15554            if (app.thread != null) {
15555                try {
15556                    if (false) {
15557                        //RuntimeException h = new RuntimeException("here");
15558                        Slog.i(TAG, "Sending new process state " + app.repProcState
15559                                + " to " + app /*, h*/);
15560                    }
15561                    app.thread.setProcessState(app.repProcState);
15562                } catch (RemoteException e) {
15563                }
15564            }
15565        }
15566        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15567                app.setProcState)) {
15568            app.lastStateTime = now;
15569            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15570                    isSleeping(), now);
15571            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15572                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15573                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15574                    + (app.nextPssTime-now) + ": " + app);
15575        } else {
15576            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15577                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15578                requestPssLocked(app, app.setProcState);
15579                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15580                        isSleeping(), now);
15581            } else if (false && DEBUG_PSS) {
15582                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15583            }
15584        }
15585        if (app.setProcState != app.curProcState) {
15586            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15587                    "Proc state change of " + app.processName
15588                    + " to " + app.curProcState);
15589            app.setProcState = app.curProcState;
15590            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15591                app.notCachedSinceIdle = false;
15592            }
15593            if (!doingAll) {
15594                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15595            } else {
15596                app.procStateChanged = true;
15597            }
15598        }
15599
15600        if (changes != 0) {
15601            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15602            int i = mPendingProcessChanges.size()-1;
15603            ProcessChangeItem item = null;
15604            while (i >= 0) {
15605                item = mPendingProcessChanges.get(i);
15606                if (item.pid == app.pid) {
15607                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15608                    break;
15609                }
15610                i--;
15611            }
15612            if (i < 0) {
15613                // No existing item in pending changes; need a new one.
15614                final int NA = mAvailProcessChanges.size();
15615                if (NA > 0) {
15616                    item = mAvailProcessChanges.remove(NA-1);
15617                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15618                } else {
15619                    item = new ProcessChangeItem();
15620                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15621                }
15622                item.changes = 0;
15623                item.pid = app.pid;
15624                item.uid = app.info.uid;
15625                if (mPendingProcessChanges.size() == 0) {
15626                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15627                            "*** Enqueueing dispatch processes changed!");
15628                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15629                }
15630                mPendingProcessChanges.add(item);
15631            }
15632            item.changes |= changes;
15633            item.processState = app.repProcState;
15634            item.foregroundActivities = app.repForegroundActivities;
15635            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15636                    + Integer.toHexString(System.identityHashCode(item))
15637                    + " " + app.toShortString() + ": changes=" + item.changes
15638                    + " procState=" + item.processState
15639                    + " foreground=" + item.foregroundActivities
15640                    + " type=" + app.adjType + " source=" + app.adjSource
15641                    + " target=" + app.adjTarget);
15642        }
15643
15644        return success;
15645    }
15646
15647    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15648        if (proc.thread != null && proc.baseProcessTracker != null) {
15649            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15650        }
15651    }
15652
15653    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15654            ProcessRecord TOP_APP, boolean doingAll, long now) {
15655        if (app.thread == null) {
15656            return false;
15657        }
15658
15659        final boolean wasKeeping = app.keeping;
15660
15661        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15662
15663        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15664    }
15665
15666    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15667            boolean oomAdj) {
15668        if (isForeground != proc.foregroundServices) {
15669            proc.foregroundServices = isForeground;
15670            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15671                    proc.info.uid);
15672            if (isForeground) {
15673                if (curProcs == null) {
15674                    curProcs = new ArrayList<ProcessRecord>();
15675                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15676                }
15677                if (!curProcs.contains(proc)) {
15678                    curProcs.add(proc);
15679                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15680                            proc.info.packageName, proc.info.uid);
15681                }
15682            } else {
15683                if (curProcs != null) {
15684                    if (curProcs.remove(proc)) {
15685                        mBatteryStatsService.noteEvent(
15686                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15687                                proc.info.packageName, proc.info.uid);
15688                        if (curProcs.size() <= 0) {
15689                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15690                        }
15691                    }
15692                }
15693            }
15694            if (oomAdj) {
15695                updateOomAdjLocked();
15696            }
15697        }
15698    }
15699
15700    private final ActivityRecord resumedAppLocked() {
15701        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15702        String pkg;
15703        int uid;
15704        if (act != null && !act.sleeping) {
15705            pkg = act.packageName;
15706            uid = act.info.applicationInfo.uid;
15707        } else {
15708            pkg = null;
15709            uid = -1;
15710        }
15711        // Has the UID or resumed package name changed?
15712        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15713                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15714            if (mCurResumedPackage != null) {
15715                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15716                        mCurResumedPackage, mCurResumedUid);
15717            }
15718            mCurResumedPackage = pkg;
15719            mCurResumedUid = uid;
15720            if (mCurResumedPackage != null) {
15721                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15722                        mCurResumedPackage, mCurResumedUid);
15723            }
15724        }
15725        return act;
15726    }
15727
15728    final boolean updateOomAdjLocked(ProcessRecord app) {
15729        final ActivityRecord TOP_ACT = resumedAppLocked();
15730        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15731        final boolean wasCached = app.cached;
15732
15733        mAdjSeq++;
15734
15735        // This is the desired cached adjusment we want to tell it to use.
15736        // If our app is currently cached, we know it, and that is it.  Otherwise,
15737        // we don't know it yet, and it needs to now be cached we will then
15738        // need to do a complete oom adj.
15739        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15740                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15741        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15742                SystemClock.uptimeMillis());
15743        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15744            // Changed to/from cached state, so apps after it in the LRU
15745            // list may also be changed.
15746            updateOomAdjLocked();
15747        }
15748        return success;
15749    }
15750
15751    final void updateOomAdjLocked() {
15752        final ActivityRecord TOP_ACT = resumedAppLocked();
15753        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15754        final long now = SystemClock.uptimeMillis();
15755        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15756        final int N = mLruProcesses.size();
15757
15758        if (false) {
15759            RuntimeException e = new RuntimeException();
15760            e.fillInStackTrace();
15761            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15762        }
15763
15764        mAdjSeq++;
15765        mNewNumServiceProcs = 0;
15766        mNewNumAServiceProcs = 0;
15767
15768        final int emptyProcessLimit;
15769        final int cachedProcessLimit;
15770        if (mProcessLimit <= 0) {
15771            emptyProcessLimit = cachedProcessLimit = 0;
15772        } else if (mProcessLimit == 1) {
15773            emptyProcessLimit = 1;
15774            cachedProcessLimit = 0;
15775        } else {
15776            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15777            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15778        }
15779
15780        // Let's determine how many processes we have running vs.
15781        // how many slots we have for background processes; we may want
15782        // to put multiple processes in a slot of there are enough of
15783        // them.
15784        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15785                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15786        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15787        if (numEmptyProcs > cachedProcessLimit) {
15788            // If there are more empty processes than our limit on cached
15789            // processes, then use the cached process limit for the factor.
15790            // This ensures that the really old empty processes get pushed
15791            // down to the bottom, so if we are running low on memory we will
15792            // have a better chance at keeping around more cached processes
15793            // instead of a gazillion empty processes.
15794            numEmptyProcs = cachedProcessLimit;
15795        }
15796        int emptyFactor = numEmptyProcs/numSlots;
15797        if (emptyFactor < 1) emptyFactor = 1;
15798        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15799        if (cachedFactor < 1) cachedFactor = 1;
15800        int stepCached = 0;
15801        int stepEmpty = 0;
15802        int numCached = 0;
15803        int numEmpty = 0;
15804        int numTrimming = 0;
15805
15806        mNumNonCachedProcs = 0;
15807        mNumCachedHiddenProcs = 0;
15808
15809        // First update the OOM adjustment for each of the
15810        // application processes based on their current state.
15811        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15812        int nextCachedAdj = curCachedAdj+1;
15813        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15814        int nextEmptyAdj = curEmptyAdj+2;
15815        for (int i=N-1; i>=0; i--) {
15816            ProcessRecord app = mLruProcesses.get(i);
15817            if (!app.killedByAm && app.thread != null) {
15818                app.procStateChanged = false;
15819                final boolean wasKeeping = app.keeping;
15820                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15821
15822                // If we haven't yet assigned the final cached adj
15823                // to the process, do that now.
15824                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15825                    switch (app.curProcState) {
15826                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15827                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15828                            // This process is a cached process holding activities...
15829                            // assign it the next cached value for that type, and then
15830                            // step that cached level.
15831                            app.curRawAdj = curCachedAdj;
15832                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15833                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15834                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15835                                    + ")");
15836                            if (curCachedAdj != nextCachedAdj) {
15837                                stepCached++;
15838                                if (stepCached >= cachedFactor) {
15839                                    stepCached = 0;
15840                                    curCachedAdj = nextCachedAdj;
15841                                    nextCachedAdj += 2;
15842                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15843                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15844                                    }
15845                                }
15846                            }
15847                            break;
15848                        default:
15849                            // For everything else, assign next empty cached process
15850                            // level and bump that up.  Note that this means that
15851                            // long-running services that have dropped down to the
15852                            // cached level will be treated as empty (since their process
15853                            // state is still as a service), which is what we want.
15854                            app.curRawAdj = curEmptyAdj;
15855                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15856                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15857                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15858                                    + ")");
15859                            if (curEmptyAdj != nextEmptyAdj) {
15860                                stepEmpty++;
15861                                if (stepEmpty >= emptyFactor) {
15862                                    stepEmpty = 0;
15863                                    curEmptyAdj = nextEmptyAdj;
15864                                    nextEmptyAdj += 2;
15865                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15866                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15867                                    }
15868                                }
15869                            }
15870                            break;
15871                    }
15872                }
15873
15874                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15875
15876                // Count the number of process types.
15877                switch (app.curProcState) {
15878                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15879                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15880                        mNumCachedHiddenProcs++;
15881                        numCached++;
15882                        if (numCached > cachedProcessLimit) {
15883                            killUnneededProcessLocked(app, "cached #" + numCached);
15884                        }
15885                        break;
15886                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15887                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15888                                && app.lastActivityTime < oldTime) {
15889                            killUnneededProcessLocked(app, "empty for "
15890                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15891                                    / 1000) + "s");
15892                        } else {
15893                            numEmpty++;
15894                            if (numEmpty > emptyProcessLimit) {
15895                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15896                            }
15897                        }
15898                        break;
15899                    default:
15900                        mNumNonCachedProcs++;
15901                        break;
15902                }
15903
15904                if (app.isolated && app.services.size() <= 0) {
15905                    // If this is an isolated process, and there are no
15906                    // services running in it, then the process is no longer
15907                    // needed.  We agressively kill these because we can by
15908                    // definition not re-use the same process again, and it is
15909                    // good to avoid having whatever code was running in them
15910                    // left sitting around after no longer needed.
15911                    killUnneededProcessLocked(app, "isolated not needed");
15912                }
15913
15914                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15915                        && !app.killedByAm) {
15916                    numTrimming++;
15917                }
15918            }
15919        }
15920
15921        mNumServiceProcs = mNewNumServiceProcs;
15922
15923        // Now determine the memory trimming level of background processes.
15924        // Unfortunately we need to start at the back of the list to do this
15925        // properly.  We only do this if the number of background apps we
15926        // are managing to keep around is less than half the maximum we desire;
15927        // if we are keeping a good number around, we'll let them use whatever
15928        // memory they want.
15929        final int numCachedAndEmpty = numCached + numEmpty;
15930        int memFactor;
15931        if (numCached <= ProcessList.TRIM_CACHED_APPS
15932                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15933            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15934                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15935            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15936                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15937            } else {
15938                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15939            }
15940        } else {
15941            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15942        }
15943        // We always allow the memory level to go up (better).  We only allow it to go
15944        // down if we are in a state where that is allowed, *and* the total number of processes
15945        // has gone down since last time.
15946        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15947                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15948                + " last=" + mLastNumProcesses);
15949        if (memFactor > mLastMemoryLevel) {
15950            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15951                memFactor = mLastMemoryLevel;
15952                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15953            }
15954        }
15955        mLastMemoryLevel = memFactor;
15956        mLastNumProcesses = mLruProcesses.size();
15957        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15958        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15959        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15960            if (mLowRamStartTime == 0) {
15961                mLowRamStartTime = now;
15962            }
15963            int step = 0;
15964            int fgTrimLevel;
15965            switch (memFactor) {
15966                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15967                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15968                    break;
15969                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15970                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15971                    break;
15972                default:
15973                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15974                    break;
15975            }
15976            int factor = numTrimming/3;
15977            int minFactor = 2;
15978            if (mHomeProcess != null) minFactor++;
15979            if (mPreviousProcess != null) minFactor++;
15980            if (factor < minFactor) factor = minFactor;
15981            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15982            for (int i=N-1; i>=0; i--) {
15983                ProcessRecord app = mLruProcesses.get(i);
15984                if (allChanged || app.procStateChanged) {
15985                    setProcessTrackerState(app, trackerMemFactor, now);
15986                    app.procStateChanged = false;
15987                }
15988                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15989                        && !app.killedByAm) {
15990                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15991                        try {
15992                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15993                                    "Trimming memory of " + app.processName
15994                                    + " to " + curLevel);
15995                            app.thread.scheduleTrimMemory(curLevel);
15996                        } catch (RemoteException e) {
15997                        }
15998                        if (false) {
15999                            // For now we won't do this; our memory trimming seems
16000                            // to be good enough at this point that destroying
16001                            // activities causes more harm than good.
16002                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16003                                    && app != mHomeProcess && app != mPreviousProcess) {
16004                                // Need to do this on its own message because the stack may not
16005                                // be in a consistent state at this point.
16006                                // For these apps we will also finish their activities
16007                                // to help them free memory.
16008                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16009                            }
16010                        }
16011                    }
16012                    app.trimMemoryLevel = curLevel;
16013                    step++;
16014                    if (step >= factor) {
16015                        step = 0;
16016                        switch (curLevel) {
16017                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16018                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16019                                break;
16020                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16021                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16022                                break;
16023                        }
16024                    }
16025                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16026                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16027                            && app.thread != null) {
16028                        try {
16029                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16030                                    "Trimming memory of heavy-weight " + app.processName
16031                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16032                            app.thread.scheduleTrimMemory(
16033                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16034                        } catch (RemoteException e) {
16035                        }
16036                    }
16037                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16038                } else {
16039                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16040                            || app.systemNoUi) && app.pendingUiClean) {
16041                        // If this application is now in the background and it
16042                        // had done UI, then give it the special trim level to
16043                        // have it free UI resources.
16044                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16045                        if (app.trimMemoryLevel < level && app.thread != null) {
16046                            try {
16047                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16048                                        "Trimming memory of bg-ui " + app.processName
16049                                        + " to " + level);
16050                                app.thread.scheduleTrimMemory(level);
16051                            } catch (RemoteException e) {
16052                            }
16053                        }
16054                        app.pendingUiClean = false;
16055                    }
16056                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16057                        try {
16058                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16059                                    "Trimming memory of fg " + app.processName
16060                                    + " to " + fgTrimLevel);
16061                            app.thread.scheduleTrimMemory(fgTrimLevel);
16062                        } catch (RemoteException e) {
16063                        }
16064                    }
16065                    app.trimMemoryLevel = fgTrimLevel;
16066                }
16067            }
16068        } else {
16069            if (mLowRamStartTime != 0) {
16070                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16071                mLowRamStartTime = 0;
16072            }
16073            for (int i=N-1; i>=0; i--) {
16074                ProcessRecord app = mLruProcesses.get(i);
16075                if (allChanged || app.procStateChanged) {
16076                    setProcessTrackerState(app, trackerMemFactor, now);
16077                    app.procStateChanged = false;
16078                }
16079                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16080                        || app.systemNoUi) && app.pendingUiClean) {
16081                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16082                            && app.thread != null) {
16083                        try {
16084                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16085                                    "Trimming memory of ui hidden " + app.processName
16086                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16087                            app.thread.scheduleTrimMemory(
16088                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16089                        } catch (RemoteException e) {
16090                        }
16091                    }
16092                    app.pendingUiClean = false;
16093                }
16094                app.trimMemoryLevel = 0;
16095            }
16096        }
16097
16098        if (mAlwaysFinishActivities) {
16099            // Need to do this on its own message because the stack may not
16100            // be in a consistent state at this point.
16101            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16102        }
16103
16104        if (allChanged) {
16105            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16106        }
16107
16108        if (mProcessStats.shouldWriteNowLocked(now)) {
16109            mHandler.post(new Runnable() {
16110                @Override public void run() {
16111                    synchronized (ActivityManagerService.this) {
16112                        mProcessStats.writeStateAsyncLocked();
16113                    }
16114                }
16115            });
16116        }
16117
16118        if (DEBUG_OOM_ADJ) {
16119            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16120        }
16121    }
16122
16123    final void trimApplications() {
16124        synchronized (this) {
16125            int i;
16126
16127            // First remove any unused application processes whose package
16128            // has been removed.
16129            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16130                final ProcessRecord app = mRemovedProcesses.get(i);
16131                if (app.activities.size() == 0
16132                        && app.curReceiver == null && app.services.size() == 0) {
16133                    Slog.i(
16134                        TAG, "Exiting empty application process "
16135                        + app.processName + " ("
16136                        + (app.thread != null ? app.thread.asBinder() : null)
16137                        + ")\n");
16138                    if (app.pid > 0 && app.pid != MY_PID) {
16139                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16140                                app.processName, app.setAdj, "empty");
16141                        app.killedByAm = true;
16142                        Process.killProcessQuiet(app.pid);
16143                    } else {
16144                        try {
16145                            app.thread.scheduleExit();
16146                        } catch (Exception e) {
16147                            // Ignore exceptions.
16148                        }
16149                    }
16150                    cleanUpApplicationRecordLocked(app, false, true, -1);
16151                    mRemovedProcesses.remove(i);
16152
16153                    if (app.persistent) {
16154                        if (app.persistent) {
16155                            addAppLocked(app.info, false);
16156                        }
16157                    }
16158                }
16159            }
16160
16161            // Now update the oom adj for all processes.
16162            updateOomAdjLocked();
16163        }
16164    }
16165
16166    /** This method sends the specified signal to each of the persistent apps */
16167    public void signalPersistentProcesses(int sig) throws RemoteException {
16168        if (sig != Process.SIGNAL_USR1) {
16169            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16170        }
16171
16172        synchronized (this) {
16173            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16174                    != PackageManager.PERMISSION_GRANTED) {
16175                throw new SecurityException("Requires permission "
16176                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16177            }
16178
16179            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16180                ProcessRecord r = mLruProcesses.get(i);
16181                if (r.thread != null && r.persistent) {
16182                    Process.sendSignal(r.pid, sig);
16183                }
16184            }
16185        }
16186    }
16187
16188    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16189        if (proc == null || proc == mProfileProc) {
16190            proc = mProfileProc;
16191            path = mProfileFile;
16192            profileType = mProfileType;
16193            clearProfilerLocked();
16194        }
16195        if (proc == null) {
16196            return;
16197        }
16198        try {
16199            proc.thread.profilerControl(false, path, null, profileType);
16200        } catch (RemoteException e) {
16201            throw new IllegalStateException("Process disappeared");
16202        }
16203    }
16204
16205    private void clearProfilerLocked() {
16206        if (mProfileFd != null) {
16207            try {
16208                mProfileFd.close();
16209            } catch (IOException e) {
16210            }
16211        }
16212        mProfileApp = null;
16213        mProfileProc = null;
16214        mProfileFile = null;
16215        mProfileType = 0;
16216        mAutoStopProfiler = false;
16217    }
16218
16219    public boolean profileControl(String process, int userId, boolean start,
16220            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16221
16222        try {
16223            synchronized (this) {
16224                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16225                // its own permission.
16226                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16227                        != PackageManager.PERMISSION_GRANTED) {
16228                    throw new SecurityException("Requires permission "
16229                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16230                }
16231
16232                if (start && fd == null) {
16233                    throw new IllegalArgumentException("null fd");
16234                }
16235
16236                ProcessRecord proc = null;
16237                if (process != null) {
16238                    proc = findProcessLocked(process, userId, "profileControl");
16239                }
16240
16241                if (start && (proc == null || proc.thread == null)) {
16242                    throw new IllegalArgumentException("Unknown process: " + process);
16243                }
16244
16245                if (start) {
16246                    stopProfilerLocked(null, null, 0);
16247                    setProfileApp(proc.info, proc.processName, path, fd, false);
16248                    mProfileProc = proc;
16249                    mProfileType = profileType;
16250                    try {
16251                        fd = fd.dup();
16252                    } catch (IOException e) {
16253                        fd = null;
16254                    }
16255                    proc.thread.profilerControl(start, path, fd, profileType);
16256                    fd = null;
16257                    mProfileFd = null;
16258                } else {
16259                    stopProfilerLocked(proc, path, profileType);
16260                    if (fd != null) {
16261                        try {
16262                            fd.close();
16263                        } catch (IOException e) {
16264                        }
16265                    }
16266                }
16267
16268                return true;
16269            }
16270        } catch (RemoteException e) {
16271            throw new IllegalStateException("Process disappeared");
16272        } finally {
16273            if (fd != null) {
16274                try {
16275                    fd.close();
16276                } catch (IOException e) {
16277                }
16278            }
16279        }
16280    }
16281
16282    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16283        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16284                userId, true, true, callName, null);
16285        ProcessRecord proc = null;
16286        try {
16287            int pid = Integer.parseInt(process);
16288            synchronized (mPidsSelfLocked) {
16289                proc = mPidsSelfLocked.get(pid);
16290            }
16291        } catch (NumberFormatException e) {
16292        }
16293
16294        if (proc == null) {
16295            ArrayMap<String, SparseArray<ProcessRecord>> all
16296                    = mProcessNames.getMap();
16297            SparseArray<ProcessRecord> procs = all.get(process);
16298            if (procs != null && procs.size() > 0) {
16299                proc = procs.valueAt(0);
16300                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16301                    for (int i=1; i<procs.size(); i++) {
16302                        ProcessRecord thisProc = procs.valueAt(i);
16303                        if (thisProc.userId == userId) {
16304                            proc = thisProc;
16305                            break;
16306                        }
16307                    }
16308                }
16309            }
16310        }
16311
16312        return proc;
16313    }
16314
16315    public boolean dumpHeap(String process, int userId, boolean managed,
16316            String path, ParcelFileDescriptor fd) throws RemoteException {
16317
16318        try {
16319            synchronized (this) {
16320                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16321                // its own permission (same as profileControl).
16322                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16323                        != PackageManager.PERMISSION_GRANTED) {
16324                    throw new SecurityException("Requires permission "
16325                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16326                }
16327
16328                if (fd == null) {
16329                    throw new IllegalArgumentException("null fd");
16330                }
16331
16332                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16333                if (proc == null || proc.thread == null) {
16334                    throw new IllegalArgumentException("Unknown process: " + process);
16335                }
16336
16337                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16338                if (!isDebuggable) {
16339                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16340                        throw new SecurityException("Process not debuggable: " + proc);
16341                    }
16342                }
16343
16344                proc.thread.dumpHeap(managed, path, fd);
16345                fd = null;
16346                return true;
16347            }
16348        } catch (RemoteException e) {
16349            throw new IllegalStateException("Process disappeared");
16350        } finally {
16351            if (fd != null) {
16352                try {
16353                    fd.close();
16354                } catch (IOException e) {
16355                }
16356            }
16357        }
16358    }
16359
16360    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16361    public void monitor() {
16362        synchronized (this) { }
16363    }
16364
16365    void onCoreSettingsChange(Bundle settings) {
16366        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16367            ProcessRecord processRecord = mLruProcesses.get(i);
16368            try {
16369                if (processRecord.thread != null) {
16370                    processRecord.thread.setCoreSettings(settings);
16371                }
16372            } catch (RemoteException re) {
16373                /* ignore */
16374            }
16375        }
16376    }
16377
16378    // Multi-user methods
16379
16380    /**
16381     * Start user, if its not already running, but don't bring it to foreground.
16382     */
16383    @Override
16384    public boolean startUserInBackground(final int userId) {
16385        return startUser(userId, /* foreground */ false);
16386    }
16387
16388    /**
16389     * Refreshes the list of users related to the current user when either a
16390     * user switch happens or when a new related user is started in the
16391     * background.
16392     */
16393    private void updateCurrentProfileIdsLocked() {
16394        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16395                mCurrentUserId, false /* enabledOnly */);
16396        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16397        for (int i = 0; i < currentProfileIds.length; i++) {
16398            currentProfileIds[i] = profiles.get(i).id;
16399        }
16400        mCurrentProfileIds = currentProfileIds;
16401    }
16402
16403    private Set getProfileIdsLocked(int userId) {
16404        Set userIds = new HashSet<Integer>();
16405        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16406                userId, false /* enabledOnly */);
16407        for (UserInfo user : profiles) {
16408            userIds.add(Integer.valueOf(user.id));
16409        }
16410        return userIds;
16411    }
16412
16413    @Override
16414    public boolean switchUser(final int userId) {
16415        return startUser(userId, /* foregound */ true);
16416    }
16417
16418    private boolean startUser(final int userId, boolean foreground) {
16419        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16420                != PackageManager.PERMISSION_GRANTED) {
16421            String msg = "Permission Denial: switchUser() from pid="
16422                    + Binder.getCallingPid()
16423                    + ", uid=" + Binder.getCallingUid()
16424                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16425            Slog.w(TAG, msg);
16426            throw new SecurityException(msg);
16427        }
16428
16429        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16430
16431        final long ident = Binder.clearCallingIdentity();
16432        try {
16433            synchronized (this) {
16434                final int oldUserId = mCurrentUserId;
16435                if (oldUserId == userId) {
16436                    return true;
16437                }
16438
16439                mStackSupervisor.setLockTaskModeLocked(null);
16440
16441                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16442                if (userInfo == null) {
16443                    Slog.w(TAG, "No user info for user #" + userId);
16444                    return false;
16445                }
16446
16447                if (foreground) {
16448                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16449                            R.anim.screen_user_enter);
16450                }
16451
16452                boolean needStart = false;
16453
16454                // If the user we are switching to is not currently started, then
16455                // we need to start it now.
16456                if (mStartedUsers.get(userId) == null) {
16457                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16458                    updateStartedUserArrayLocked();
16459                    needStart = true;
16460                }
16461
16462                final Integer userIdInt = Integer.valueOf(userId);
16463                mUserLru.remove(userIdInt);
16464                mUserLru.add(userIdInt);
16465
16466                if (foreground) {
16467                    mCurrentUserId = userId;
16468                    updateCurrentProfileIdsLocked();
16469                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16470                    // Once the internal notion of the active user has switched, we lock the device
16471                    // with the option to show the user switcher on the keyguard.
16472                    mWindowManager.lockNow(null);
16473                } else {
16474                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16475                    updateCurrentProfileIdsLocked();
16476                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16477                    mUserLru.remove(currentUserIdInt);
16478                    mUserLru.add(currentUserIdInt);
16479                }
16480
16481                final UserStartedState uss = mStartedUsers.get(userId);
16482
16483                // Make sure user is in the started state.  If it is currently
16484                // stopping, we need to knock that off.
16485                if (uss.mState == UserStartedState.STATE_STOPPING) {
16486                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16487                    // so we can just fairly silently bring the user back from
16488                    // the almost-dead.
16489                    uss.mState = UserStartedState.STATE_RUNNING;
16490                    updateStartedUserArrayLocked();
16491                    needStart = true;
16492                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16493                    // This means ACTION_SHUTDOWN has been sent, so we will
16494                    // need to treat this as a new boot of the user.
16495                    uss.mState = UserStartedState.STATE_BOOTING;
16496                    updateStartedUserArrayLocked();
16497                    needStart = true;
16498                }
16499
16500                if (uss.mState == UserStartedState.STATE_BOOTING) {
16501                    // Booting up a new user, need to tell system services about it.
16502                    // Note that this is on the same handler as scheduling of broadcasts,
16503                    // which is important because it needs to go first.
16504                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16505                }
16506
16507                if (foreground) {
16508                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16509                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16510                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16511                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16512                            oldUserId, userId, uss));
16513                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16514                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16515                }
16516
16517                if (needStart) {
16518                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16519                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16520                            | Intent.FLAG_RECEIVER_FOREGROUND);
16521                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16522                    broadcastIntentLocked(null, null, intent,
16523                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16524                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16525                }
16526
16527                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16528                    if (userId != UserHandle.USER_OWNER) {
16529                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16530                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16531                        broadcastIntentLocked(null, null, intent, null,
16532                                new IIntentReceiver.Stub() {
16533                                    public void performReceive(Intent intent, int resultCode,
16534                                            String data, Bundle extras, boolean ordered,
16535                                            boolean sticky, int sendingUser) {
16536                                        userInitialized(uss, userId);
16537                                    }
16538                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16539                                true, false, MY_PID, Process.SYSTEM_UID,
16540                                userId);
16541                        uss.initializing = true;
16542                    } else {
16543                        getUserManagerLocked().makeInitialized(userInfo.id);
16544                    }
16545                }
16546
16547                if (foreground) {
16548                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16549                    if (homeInFront) {
16550                        startHomeActivityLocked(userId);
16551                    } else {
16552                        mStackSupervisor.resumeTopActivitiesLocked();
16553                    }
16554                    EventLogTags.writeAmSwitchUser(userId);
16555                    getUserManagerLocked().userForeground(userId);
16556                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16557                } else {
16558                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16559                }
16560
16561                if (needStart) {
16562                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16563                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16564                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16565                    broadcastIntentLocked(null, null, intent,
16566                            null, new IIntentReceiver.Stub() {
16567                                @Override
16568                                public void performReceive(Intent intent, int resultCode, String data,
16569                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16570                                        throws RemoteException {
16571                                }
16572                            }, 0, null, null,
16573                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16574                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16575                }
16576            }
16577        } finally {
16578            Binder.restoreCallingIdentity(ident);
16579        }
16580
16581        return true;
16582    }
16583
16584    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16585        long ident = Binder.clearCallingIdentity();
16586        try {
16587            Intent intent;
16588            if (oldUserId >= 0) {
16589                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16590                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16591                        | Intent.FLAG_RECEIVER_FOREGROUND);
16592                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16593                broadcastIntentLocked(null, null, intent,
16594                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16595                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16596            }
16597            if (newUserId >= 0) {
16598                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16599                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16600                        | Intent.FLAG_RECEIVER_FOREGROUND);
16601                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16602                broadcastIntentLocked(null, null, intent,
16603                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16604                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16605                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16606                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16607                        | Intent.FLAG_RECEIVER_FOREGROUND);
16608                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16609                broadcastIntentLocked(null, null, intent,
16610                        null, null, 0, null, null,
16611                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16612                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16613            }
16614        } finally {
16615            Binder.restoreCallingIdentity(ident);
16616        }
16617    }
16618
16619    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16620            final int newUserId) {
16621        final int N = mUserSwitchObservers.beginBroadcast();
16622        if (N > 0) {
16623            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16624                int mCount = 0;
16625                @Override
16626                public void sendResult(Bundle data) throws RemoteException {
16627                    synchronized (ActivityManagerService.this) {
16628                        if (mCurUserSwitchCallback == this) {
16629                            mCount++;
16630                            if (mCount == N) {
16631                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16632                            }
16633                        }
16634                    }
16635                }
16636            };
16637            synchronized (this) {
16638                uss.switching = true;
16639                mCurUserSwitchCallback = callback;
16640            }
16641            for (int i=0; i<N; i++) {
16642                try {
16643                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16644                            newUserId, callback);
16645                } catch (RemoteException e) {
16646                }
16647            }
16648        } else {
16649            synchronized (this) {
16650                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16651            }
16652        }
16653        mUserSwitchObservers.finishBroadcast();
16654    }
16655
16656    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16657        synchronized (this) {
16658            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16659            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16660        }
16661    }
16662
16663    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16664        mCurUserSwitchCallback = null;
16665        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16666        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16667                oldUserId, newUserId, uss));
16668    }
16669
16670    void userInitialized(UserStartedState uss, int newUserId) {
16671        completeSwitchAndInitalize(uss, newUserId, true, false);
16672    }
16673
16674    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16675        completeSwitchAndInitalize(uss, newUserId, false, true);
16676    }
16677
16678    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16679            boolean clearInitializing, boolean clearSwitching) {
16680        boolean unfrozen = false;
16681        synchronized (this) {
16682            if (clearInitializing) {
16683                uss.initializing = false;
16684                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16685            }
16686            if (clearSwitching) {
16687                uss.switching = false;
16688            }
16689            if (!uss.switching && !uss.initializing) {
16690                mWindowManager.stopFreezingScreen();
16691                unfrozen = true;
16692            }
16693        }
16694        if (unfrozen) {
16695            final int N = mUserSwitchObservers.beginBroadcast();
16696            for (int i=0; i<N; i++) {
16697                try {
16698                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16699                } catch (RemoteException e) {
16700                }
16701            }
16702            mUserSwitchObservers.finishBroadcast();
16703        }
16704    }
16705
16706    void scheduleStartProfilesLocked() {
16707        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16708            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16709                    DateUtils.SECOND_IN_MILLIS);
16710        }
16711    }
16712
16713    void startProfilesLocked() {
16714        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16715        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16716                mCurrentUserId, false /* enabledOnly */);
16717        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16718        for (UserInfo user : profiles) {
16719            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16720                    && user.id != mCurrentUserId) {
16721                toStart.add(user);
16722            }
16723        }
16724        final int n = toStart.size();
16725        int i = 0;
16726        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16727            startUserInBackground(toStart.get(i).id);
16728        }
16729        if (i < n) {
16730            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16731        }
16732    }
16733
16734    void finishUserBoot(UserStartedState uss) {
16735        synchronized (this) {
16736            if (uss.mState == UserStartedState.STATE_BOOTING
16737                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16738                uss.mState = UserStartedState.STATE_RUNNING;
16739                final int userId = uss.mHandle.getIdentifier();
16740                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16741                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16742                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16743                broadcastIntentLocked(null, null, intent,
16744                        null, null, 0, null, null,
16745                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16746                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16747            }
16748        }
16749    }
16750
16751    void finishUserSwitch(UserStartedState uss) {
16752        synchronized (this) {
16753            finishUserBoot(uss);
16754
16755            startProfilesLocked();
16756
16757            int num = mUserLru.size();
16758            int i = 0;
16759            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16760                Integer oldUserId = mUserLru.get(i);
16761                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16762                if (oldUss == null) {
16763                    // Shouldn't happen, but be sane if it does.
16764                    mUserLru.remove(i);
16765                    num--;
16766                    continue;
16767                }
16768                if (oldUss.mState == UserStartedState.STATE_STOPPING
16769                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16770                    // This user is already stopping, doesn't count.
16771                    num--;
16772                    i++;
16773                    continue;
16774                }
16775                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16776                    // Owner and current can't be stopped, but count as running.
16777                    i++;
16778                    continue;
16779                }
16780                // This is a user to be stopped.
16781                stopUserLocked(oldUserId, null);
16782                num--;
16783                i++;
16784            }
16785        }
16786    }
16787
16788    @Override
16789    public int stopUser(final int userId, final IStopUserCallback callback) {
16790        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16791                != PackageManager.PERMISSION_GRANTED) {
16792            String msg = "Permission Denial: switchUser() from pid="
16793                    + Binder.getCallingPid()
16794                    + ", uid=" + Binder.getCallingUid()
16795                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16796            Slog.w(TAG, msg);
16797            throw new SecurityException(msg);
16798        }
16799        if (userId <= 0) {
16800            throw new IllegalArgumentException("Can't stop primary user " + userId);
16801        }
16802        synchronized (this) {
16803            return stopUserLocked(userId, callback);
16804        }
16805    }
16806
16807    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16808        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16809        if (mCurrentUserId == userId) {
16810            return ActivityManager.USER_OP_IS_CURRENT;
16811        }
16812
16813        final UserStartedState uss = mStartedUsers.get(userId);
16814        if (uss == null) {
16815            // User is not started, nothing to do...  but we do need to
16816            // callback if requested.
16817            if (callback != null) {
16818                mHandler.post(new Runnable() {
16819                    @Override
16820                    public void run() {
16821                        try {
16822                            callback.userStopped(userId);
16823                        } catch (RemoteException e) {
16824                        }
16825                    }
16826                });
16827            }
16828            return ActivityManager.USER_OP_SUCCESS;
16829        }
16830
16831        if (callback != null) {
16832            uss.mStopCallbacks.add(callback);
16833        }
16834
16835        if (uss.mState != UserStartedState.STATE_STOPPING
16836                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16837            uss.mState = UserStartedState.STATE_STOPPING;
16838            updateStartedUserArrayLocked();
16839
16840            long ident = Binder.clearCallingIdentity();
16841            try {
16842                // We are going to broadcast ACTION_USER_STOPPING and then
16843                // once that is done send a final ACTION_SHUTDOWN and then
16844                // stop the user.
16845                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16846                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16847                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16848                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16849                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16850                // This is the result receiver for the final shutdown broadcast.
16851                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16852                    @Override
16853                    public void performReceive(Intent intent, int resultCode, String data,
16854                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16855                        finishUserStop(uss);
16856                    }
16857                };
16858                // This is the result receiver for the initial stopping broadcast.
16859                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16860                    @Override
16861                    public void performReceive(Intent intent, int resultCode, String data,
16862                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16863                        // On to the next.
16864                        synchronized (ActivityManagerService.this) {
16865                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16866                                // Whoops, we are being started back up.  Abort, abort!
16867                                return;
16868                            }
16869                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16870                        }
16871                        mSystemServiceManager.stopUser(userId);
16872                        broadcastIntentLocked(null, null, shutdownIntent,
16873                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16874                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16875                    }
16876                };
16877                // Kick things off.
16878                broadcastIntentLocked(null, null, stoppingIntent,
16879                        null, stoppingReceiver, 0, null, null,
16880                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16881                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16882            } finally {
16883                Binder.restoreCallingIdentity(ident);
16884            }
16885        }
16886
16887        return ActivityManager.USER_OP_SUCCESS;
16888    }
16889
16890    void finishUserStop(UserStartedState uss) {
16891        final int userId = uss.mHandle.getIdentifier();
16892        boolean stopped;
16893        ArrayList<IStopUserCallback> callbacks;
16894        synchronized (this) {
16895            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16896            if (mStartedUsers.get(userId) != uss) {
16897                stopped = false;
16898            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16899                stopped = false;
16900            } else {
16901                stopped = true;
16902                // User can no longer run.
16903                mStartedUsers.remove(userId);
16904                mUserLru.remove(Integer.valueOf(userId));
16905                updateStartedUserArrayLocked();
16906
16907                // Clean up all state and processes associated with the user.
16908                // Kill all the processes for the user.
16909                forceStopUserLocked(userId, "finish user");
16910            }
16911        }
16912
16913        for (int i=0; i<callbacks.size(); i++) {
16914            try {
16915                if (stopped) callbacks.get(i).userStopped(userId);
16916                else callbacks.get(i).userStopAborted(userId);
16917            } catch (RemoteException e) {
16918            }
16919        }
16920
16921        if (stopped) {
16922            mSystemServiceManager.cleanupUser(userId);
16923            synchronized (this) {
16924                mStackSupervisor.removeUserLocked(userId);
16925            }
16926        }
16927    }
16928
16929    @Override
16930    public UserInfo getCurrentUser() {
16931        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16932                != PackageManager.PERMISSION_GRANTED) && (
16933                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16934                != PackageManager.PERMISSION_GRANTED)) {
16935            String msg = "Permission Denial: getCurrentUser() from pid="
16936                    + Binder.getCallingPid()
16937                    + ", uid=" + Binder.getCallingUid()
16938                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16939            Slog.w(TAG, msg);
16940            throw new SecurityException(msg);
16941        }
16942        synchronized (this) {
16943            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16944        }
16945    }
16946
16947    int getCurrentUserIdLocked() {
16948        return mCurrentUserId;
16949    }
16950
16951    @Override
16952    public boolean isUserRunning(int userId, boolean orStopped) {
16953        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16954                != PackageManager.PERMISSION_GRANTED) {
16955            String msg = "Permission Denial: isUserRunning() from pid="
16956                    + Binder.getCallingPid()
16957                    + ", uid=" + Binder.getCallingUid()
16958                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16959            Slog.w(TAG, msg);
16960            throw new SecurityException(msg);
16961        }
16962        synchronized (this) {
16963            return isUserRunningLocked(userId, orStopped);
16964        }
16965    }
16966
16967    boolean isUserRunningLocked(int userId, boolean orStopped) {
16968        UserStartedState state = mStartedUsers.get(userId);
16969        if (state == null) {
16970            return false;
16971        }
16972        if (orStopped) {
16973            return true;
16974        }
16975        return state.mState != UserStartedState.STATE_STOPPING
16976                && state.mState != UserStartedState.STATE_SHUTDOWN;
16977    }
16978
16979    @Override
16980    public int[] getRunningUserIds() {
16981        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16982                != PackageManager.PERMISSION_GRANTED) {
16983            String msg = "Permission Denial: isUserRunning() from pid="
16984                    + Binder.getCallingPid()
16985                    + ", uid=" + Binder.getCallingUid()
16986                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16987            Slog.w(TAG, msg);
16988            throw new SecurityException(msg);
16989        }
16990        synchronized (this) {
16991            return mStartedUserArray;
16992        }
16993    }
16994
16995    private void updateStartedUserArrayLocked() {
16996        int num = 0;
16997        for (int i=0; i<mStartedUsers.size();  i++) {
16998            UserStartedState uss = mStartedUsers.valueAt(i);
16999            // This list does not include stopping users.
17000            if (uss.mState != UserStartedState.STATE_STOPPING
17001                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17002                num++;
17003            }
17004        }
17005        mStartedUserArray = new int[num];
17006        num = 0;
17007        for (int i=0; i<mStartedUsers.size();  i++) {
17008            UserStartedState uss = mStartedUsers.valueAt(i);
17009            if (uss.mState != UserStartedState.STATE_STOPPING
17010                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17011                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17012                num++;
17013            }
17014        }
17015    }
17016
17017    @Override
17018    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17019        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17020                != PackageManager.PERMISSION_GRANTED) {
17021            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17022                    + Binder.getCallingPid()
17023                    + ", uid=" + Binder.getCallingUid()
17024                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17025            Slog.w(TAG, msg);
17026            throw new SecurityException(msg);
17027        }
17028
17029        mUserSwitchObservers.register(observer);
17030    }
17031
17032    @Override
17033    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17034        mUserSwitchObservers.unregister(observer);
17035    }
17036
17037    private boolean userExists(int userId) {
17038        if (userId == 0) {
17039            return true;
17040        }
17041        UserManagerService ums = getUserManagerLocked();
17042        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17043    }
17044
17045    int[] getUsersLocked() {
17046        UserManagerService ums = getUserManagerLocked();
17047        return ums != null ? ums.getUserIds() : new int[] { 0 };
17048    }
17049
17050    UserManagerService getUserManagerLocked() {
17051        if (mUserManager == null) {
17052            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17053            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17054        }
17055        return mUserManager;
17056    }
17057
17058    private int applyUserId(int uid, int userId) {
17059        return UserHandle.getUid(userId, uid);
17060    }
17061
17062    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17063        if (info == null) return null;
17064        ApplicationInfo newInfo = new ApplicationInfo(info);
17065        newInfo.uid = applyUserId(info.uid, userId);
17066        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17067                + info.packageName;
17068        return newInfo;
17069    }
17070
17071    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17072        if (aInfo == null
17073                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17074            return aInfo;
17075        }
17076
17077        ActivityInfo info = new ActivityInfo(aInfo);
17078        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17079        return info;
17080    }
17081
17082    private final class LocalService extends ActivityManagerInternal {
17083        @Override
17084        public void goingToSleep() {
17085            ActivityManagerService.this.goingToSleep();
17086        }
17087
17088        @Override
17089        public void wakingUp() {
17090            ActivityManagerService.this.wakingUp();
17091        }
17092    }
17093}
17094