ActivityManagerService.java revision 3c153519ca5f2b66b88901374383f943c9d77df7
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.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162
1163    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1164    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1165    static final int FIRST_COMPAT_MODE_MSG = 300;
1166    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1167
1168    AlertDialog mUidAlert;
1169    CompatModeDialog mCompatModeDialog;
1170    long mLastMemUsageReportTime = 0;
1171
1172    private LockToAppRequestDialog mLockToAppRequest;
1173
1174    /**
1175     * Flag whether the current user is a "monkey", i.e. whether
1176     * the UI is driven by a UI automation tool.
1177     */
1178    private boolean mUserIsMonkey;
1179
1180    /** Flag whether the device has a recents UI */
1181    final boolean mHasRecents;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1803                        Integer.toString(msg.arg1), msg.arg1);
1804                mSystemServiceManager.startUser(msg.arg1);
1805                break;
1806            }
1807            case SYSTEM_USER_CURRENT_MSG: {
1808                mBatteryStatsService.noteEvent(
1809                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1810                        Integer.toString(msg.arg2), msg.arg2);
1811                mBatteryStatsService.noteEvent(
1812                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1813                        Integer.toString(msg.arg1), msg.arg1);
1814                mSystemServiceManager.switchUser(msg.arg1);
1815                break;
1816            }
1817            case ENTER_ANIMATION_COMPLETE_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1820                    if (r != null && r.app != null && r.app.thread != null) {
1821                        try {
1822                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1823                        } catch (RemoteException e) {
1824                        }
1825                    }
1826                }
1827                break;
1828            }
1829            }
1830        }
1831    };
1832
1833    static final int COLLECT_PSS_BG_MSG = 1;
1834
1835    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1836        @Override
1837        public void handleMessage(Message msg) {
1838            switch (msg.what) {
1839            case COLLECT_PSS_BG_MSG: {
1840                long start = SystemClock.uptimeMillis();
1841                MemInfoReader memInfo = null;
1842                synchronized (ActivityManagerService.this) {
1843                    if (mFullPssPending) {
1844                        mFullPssPending = false;
1845                        memInfo = new MemInfoReader();
1846                    }
1847                }
1848                if (memInfo != null) {
1849                    updateCpuStatsNow();
1850                    long nativeTotalPss = 0;
1851                    synchronized (mProcessCpuThread) {
1852                        final int N = mProcessCpuTracker.countStats();
1853                        for (int j=0; j<N; j++) {
1854                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1855                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1856                                // This is definitely an application process; skip it.
1857                                continue;
1858                            }
1859                            synchronized (mPidsSelfLocked) {
1860                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1861                                    // This is one of our own processes; skip it.
1862                                    continue;
1863                                }
1864                            }
1865                            nativeTotalPss += Debug.getPss(st.pid, null);
1866                        }
1867                    }
1868                    memInfo.readMemInfo();
1869                    synchronized (this) {
1870                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1871                                + (SystemClock.uptimeMillis()-start) + "ms");
1872                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1873                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1874                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1875                                        +memInfo.getSlabSizeKb(),
1876                                nativeTotalPss);
1877                    }
1878                }
1879
1880                int i=0, num=0;
1881                long[] tmp = new long[1];
1882                do {
1883                    ProcessRecord proc;
1884                    int procState;
1885                    int pid;
1886                    synchronized (ActivityManagerService.this) {
1887                        if (i >= mPendingPssProcesses.size()) {
1888                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1889                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1890                            mPendingPssProcesses.clear();
1891                            return;
1892                        }
1893                        proc = mPendingPssProcesses.get(i);
1894                        procState = proc.pssProcState;
1895                        if (proc.thread != null && procState == proc.setProcState) {
1896                            pid = proc.pid;
1897                        } else {
1898                            proc = null;
1899                            pid = 0;
1900                        }
1901                        i++;
1902                    }
1903                    if (proc != null) {
1904                        long pss = Debug.getPss(pid, tmp);
1905                        synchronized (ActivityManagerService.this) {
1906                            if (proc.thread != null && proc.setProcState == procState
1907                                    && proc.pid == pid) {
1908                                num++;
1909                                proc.lastPssTime = SystemClock.uptimeMillis();
1910                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1911                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1912                                        + ": " + pss + " lastPss=" + proc.lastPss
1913                                        + " state=" + ProcessList.makeProcStateString(procState));
1914                                if (proc.initialIdlePss == 0) {
1915                                    proc.initialIdlePss = pss;
1916                                }
1917                                proc.lastPss = pss;
1918                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1919                                    proc.lastCachedPss = pss;
1920                                }
1921                            }
1922                        }
1923                    }
1924                } while (true);
1925            }
1926            }
1927        }
1928    };
1929
1930    /**
1931     * Monitor for package changes and update our internal state.
1932     */
1933    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1934        @Override
1935        public void onPackageRemoved(String packageName, int uid) {
1936            // Remove all tasks with activities in the specified package from the list of recent tasks
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    ComponentName cn = tr.intent.getComponent();
1941                    if (cn != null && cn.getPackageName().equals(packageName)) {
1942                        // If the package name matches, remove the task and kill the process
1943                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1944                    }
1945                }
1946            }
1947        }
1948
1949        @Override
1950        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1951            onPackageModified(packageName);
1952            return true;
1953        }
1954
1955        @Override
1956        public void onPackageModified(String packageName) {
1957            final PackageManager pm = mContext.getPackageManager();
1958            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1959                    new ArrayList<Pair<Intent, Integer>>();
1960            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1961            // Copy the list of recent tasks so that we don't hold onto the lock on
1962            // ActivityManagerService for long periods while checking if components exist.
1963            synchronized (ActivityManagerService.this) {
1964                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1965                    TaskRecord tr = mRecentTasks.get(i);
1966                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1967                }
1968            }
1969            // Check the recent tasks and filter out all tasks with components that no longer exist.
1970            Intent tmpI = new Intent();
1971            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1972                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1973                ComponentName cn = p.first.getComponent();
1974                if (cn != null && cn.getPackageName().equals(packageName)) {
1975                    try {
1976                        // Add the task to the list to remove if the component no longer exists
1977                        tmpI.setComponent(cn);
1978                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1979                            tasksToRemove.add(p.second);
1980                        }
1981                    } catch (Exception e) {}
1982                }
1983            }
1984            // Prune all the tasks with removed components from the list of recent tasks
1985            synchronized (ActivityManagerService.this) {
1986                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1987                    // Remove the task but don't kill the process (since other components in that
1988                    // package may still be running and in the background)
1989                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1996            // Force stop the specified packages
1997            if (packages != null) {
1998                for (String pkg : packages) {
1999                    synchronized (ActivityManagerService.this) {
2000                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2001                                "finished booting")) {
2002                            return true;
2003                        }
2004                    }
2005                }
2006            }
2007            return false;
2008        }
2009    };
2010
2011    public void setSystemProcess() {
2012        try {
2013            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2014            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2015            ServiceManager.addService("meminfo", new MemBinder(this));
2016            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2017            ServiceManager.addService("dbinfo", new DbBinder(this));
2018            if (MONITOR_CPU_USAGE) {
2019                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2020            }
2021            ServiceManager.addService("permission", new PermissionController(this));
2022
2023            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2024                    "android", STOCK_PM_FLAGS);
2025            mSystemThread.installSystemApplicationInfo(info);
2026
2027            synchronized (this) {
2028                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2029                app.persistent = true;
2030                app.pid = MY_PID;
2031                app.maxAdj = ProcessList.SYSTEM_ADJ;
2032                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2033                mProcessNames.put(app.processName, app.uid, app);
2034                synchronized (mPidsSelfLocked) {
2035                    mPidsSelfLocked.put(app.pid, app);
2036                }
2037                updateLruProcessLocked(app, false, null);
2038                updateOomAdjLocked();
2039            }
2040        } catch (PackageManager.NameNotFoundException e) {
2041            throw new RuntimeException(
2042                    "Unable to find android system package", e);
2043        }
2044    }
2045
2046    public void setWindowManager(WindowManagerService wm) {
2047        mWindowManager = wm;
2048        mStackSupervisor.setWindowManager(wm);
2049    }
2050
2051    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2052        mUsageStatsService = usageStatsManager;
2053    }
2054
2055    public void startObservingNativeCrashes() {
2056        final NativeCrashListener ncl = new NativeCrashListener(this);
2057        ncl.start();
2058    }
2059
2060    public IAppOpsService getAppOpsService() {
2061        return mAppOpsService;
2062    }
2063
2064    static class MemBinder extends Binder {
2065        ActivityManagerService mActivityManagerService;
2066        MemBinder(ActivityManagerService activityManagerService) {
2067            mActivityManagerService = activityManagerService;
2068        }
2069
2070        @Override
2071        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2072            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2073                    != PackageManager.PERMISSION_GRANTED) {
2074                pw.println("Permission Denial: can't dump meminfo from from pid="
2075                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2076                        + " without permission " + android.Manifest.permission.DUMP);
2077                return;
2078            }
2079
2080            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2081        }
2082    }
2083
2084    static class GraphicsBinder extends Binder {
2085        ActivityManagerService mActivityManagerService;
2086        GraphicsBinder(ActivityManagerService activityManagerService) {
2087            mActivityManagerService = activityManagerService;
2088        }
2089
2090        @Override
2091        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2092            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2093                    != PackageManager.PERMISSION_GRANTED) {
2094                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2095                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2096                        + " without permission " + android.Manifest.permission.DUMP);
2097                return;
2098            }
2099
2100            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2101        }
2102    }
2103
2104    static class DbBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        DbBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump dbinfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpDbInfo(fd, pw, args);
2121        }
2122    }
2123
2124    static class CpuBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        CpuBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            synchronized (mActivityManagerService.mProcessCpuThread) {
2141                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2142                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2143                        SystemClock.uptimeMillis()));
2144            }
2145        }
2146    }
2147
2148    public static final class Lifecycle extends SystemService {
2149        private final ActivityManagerService mService;
2150
2151        public Lifecycle(Context context) {
2152            super(context);
2153            mService = new ActivityManagerService(context);
2154        }
2155
2156        @Override
2157        public void onStart() {
2158            mService.start();
2159        }
2160
2161        public ActivityManagerService getService() {
2162            return mService;
2163        }
2164    }
2165
2166    // Note: This method is invoked on the main thread but may need to attach various
2167    // handlers to other threads.  So take care to be explicit about the looper.
2168    public ActivityManagerService(Context systemContext) {
2169        mContext = systemContext;
2170        mFactoryTest = FactoryTest.getMode();
2171        mSystemThread = ActivityThread.currentActivityThread();
2172
2173        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2174
2175        mHandlerThread = new ServiceThread(TAG,
2176                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2177        mHandlerThread.start();
2178        mHandler = new MainHandler(mHandlerThread.getLooper());
2179
2180        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2181                "foreground", BROADCAST_FG_TIMEOUT, false);
2182        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2183                "background", BROADCAST_BG_TIMEOUT, true);
2184        mBroadcastQueues[0] = mFgBroadcastQueue;
2185        mBroadcastQueues[1] = mBgBroadcastQueue;
2186
2187        mServices = new ActiveServices(this);
2188        mProviderMap = new ProviderMap(this);
2189
2190        // TODO: Move creation of battery stats service outside of activity manager service.
2191        File dataDir = Environment.getDataDirectory();
2192        File systemDir = new File(dataDir, "system");
2193        systemDir.mkdirs();
2194        mBatteryStatsService = new BatteryStatsService(new File(
2195                systemDir, "batterystats.bin").toString(), mHandler);
2196        mBatteryStatsService.getActiveStatistics().readLocked();
2197        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2198        mOnBattery = DEBUG_POWER ? true
2199                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2200        mBatteryStatsService.getActiveStatistics().setCallback(this);
2201
2202        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2203
2204        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2205
2206        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2207
2208        // User 0 is the first and only user that runs at boot.
2209        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2210        mUserLru.add(Integer.valueOf(0));
2211        updateStartedUserArrayLocked();
2212
2213        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2214            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2215
2216        mConfiguration.setToDefaults();
2217        mConfiguration.setLocale(Locale.getDefault());
2218
2219        mConfigurationSeq = mConfiguration.seq = 1;
2220        mProcessCpuTracker.init();
2221
2222        mHasRecents = mContext.getResources().getBoolean(
2223                com.android.internal.R.bool.config_hasRecents);
2224
2225        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2226        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2227        mStackSupervisor = new ActivityStackSupervisor(this);
2228        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2229
2230        mProcessCpuThread = new Thread("CpuTracker") {
2231            @Override
2232            public void run() {
2233                while (true) {
2234                    try {
2235                        try {
2236                            synchronized(this) {
2237                                final long now = SystemClock.uptimeMillis();
2238                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2239                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2240                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2241                                //        + ", write delay=" + nextWriteDelay);
2242                                if (nextWriteDelay < nextCpuDelay) {
2243                                    nextCpuDelay = nextWriteDelay;
2244                                }
2245                                if (nextCpuDelay > 0) {
2246                                    mProcessCpuMutexFree.set(true);
2247                                    this.wait(nextCpuDelay);
2248                                }
2249                            }
2250                        } catch (InterruptedException e) {
2251                        }
2252                        updateCpuStatsNow();
2253                    } catch (Exception e) {
2254                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2255                    }
2256                }
2257            }
2258        };
2259
2260        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2261
2262        Watchdog.getInstance().addMonitor(this);
2263        Watchdog.getInstance().addThread(mHandler);
2264    }
2265
2266    public void setSystemServiceManager(SystemServiceManager mgr) {
2267        mSystemServiceManager = mgr;
2268    }
2269
2270    private void start() {
2271        Process.removeAllProcessGroups();
2272        mProcessCpuThread.start();
2273
2274        mBatteryStatsService.publish(mContext);
2275        mAppOpsService.publish(mContext);
2276        Slog.d("AppOps", "AppOpsService published");
2277        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2278    }
2279
2280    public void initPowerManagement() {
2281        mStackSupervisor.initPowerManagement();
2282        mBatteryStatsService.initPowerManagement();
2283    }
2284
2285    @Override
2286    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2287            throws RemoteException {
2288        if (code == SYSPROPS_TRANSACTION) {
2289            // We need to tell all apps about the system property change.
2290            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2291            synchronized(this) {
2292                final int NP = mProcessNames.getMap().size();
2293                for (int ip=0; ip<NP; ip++) {
2294                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2295                    final int NA = apps.size();
2296                    for (int ia=0; ia<NA; ia++) {
2297                        ProcessRecord app = apps.valueAt(ia);
2298                        if (app.thread != null) {
2299                            procs.add(app.thread.asBinder());
2300                        }
2301                    }
2302                }
2303            }
2304
2305            int N = procs.size();
2306            for (int i=0; i<N; i++) {
2307                Parcel data2 = Parcel.obtain();
2308                try {
2309                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2310                } catch (RemoteException e) {
2311                }
2312                data2.recycle();
2313            }
2314        }
2315        try {
2316            return super.onTransact(code, data, reply, flags);
2317        } catch (RuntimeException e) {
2318            // The activity manager only throws security exceptions, so let's
2319            // log all others.
2320            if (!(e instanceof SecurityException)) {
2321                Slog.wtf(TAG, "Activity Manager Crash", e);
2322            }
2323            throw e;
2324        }
2325    }
2326
2327    void updateCpuStats() {
2328        final long now = SystemClock.uptimeMillis();
2329        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2330            return;
2331        }
2332        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2333            synchronized (mProcessCpuThread) {
2334                mProcessCpuThread.notify();
2335            }
2336        }
2337    }
2338
2339    void updateCpuStatsNow() {
2340        synchronized (mProcessCpuThread) {
2341            mProcessCpuMutexFree.set(false);
2342            final long now = SystemClock.uptimeMillis();
2343            boolean haveNewCpuStats = false;
2344
2345            if (MONITOR_CPU_USAGE &&
2346                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2347                mLastCpuTime.set(now);
2348                haveNewCpuStats = true;
2349                mProcessCpuTracker.update();
2350                //Slog.i(TAG, mProcessCpu.printCurrentState());
2351                //Slog.i(TAG, "Total CPU usage: "
2352                //        + mProcessCpu.getTotalCpuPercent() + "%");
2353
2354                // Slog the cpu usage if the property is set.
2355                if ("true".equals(SystemProperties.get("events.cpu"))) {
2356                    int user = mProcessCpuTracker.getLastUserTime();
2357                    int system = mProcessCpuTracker.getLastSystemTime();
2358                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2359                    int irq = mProcessCpuTracker.getLastIrqTime();
2360                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2361                    int idle = mProcessCpuTracker.getLastIdleTime();
2362
2363                    int total = user + system + iowait + irq + softIrq + idle;
2364                    if (total == 0) total = 1;
2365
2366                    EventLog.writeEvent(EventLogTags.CPU,
2367                            ((user+system+iowait+irq+softIrq) * 100) / total,
2368                            (user * 100) / total,
2369                            (system * 100) / total,
2370                            (iowait * 100) / total,
2371                            (irq * 100) / total,
2372                            (softIrq * 100) / total);
2373                }
2374            }
2375
2376            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2377            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2378            synchronized(bstats) {
2379                synchronized(mPidsSelfLocked) {
2380                    if (haveNewCpuStats) {
2381                        if (mOnBattery) {
2382                            int perc = bstats.startAddingCpuLocked();
2383                            int totalUTime = 0;
2384                            int totalSTime = 0;
2385                            final int N = mProcessCpuTracker.countStats();
2386                            for (int i=0; i<N; i++) {
2387                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2388                                if (!st.working) {
2389                                    continue;
2390                                }
2391                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2392                                int otherUTime = (st.rel_utime*perc)/100;
2393                                int otherSTime = (st.rel_stime*perc)/100;
2394                                totalUTime += otherUTime;
2395                                totalSTime += otherSTime;
2396                                if (pr != null) {
2397                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2398                                    if (ps == null || !ps.isActive()) {
2399                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2400                                                pr.info.uid, pr.processName);
2401                                    }
2402                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2403                                            st.rel_stime-otherSTime);
2404                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2405                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2406                                } else {
2407                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2408                                    if (ps == null || !ps.isActive()) {
2409                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2410                                                bstats.mapUid(st.uid), st.name);
2411                                    }
2412                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2413                                            st.rel_stime-otherSTime);
2414                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2415                                }
2416                            }
2417                            bstats.finishAddingCpuLocked(perc, totalUTime,
2418                                    totalSTime, cpuSpeedTimes);
2419                        }
2420                    }
2421                }
2422
2423                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2424                    mLastWriteTime = now;
2425                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2426                }
2427            }
2428        }
2429    }
2430
2431    @Override
2432    public void batteryNeedsCpuUpdate() {
2433        updateCpuStatsNow();
2434    }
2435
2436    @Override
2437    public void batteryPowerChanged(boolean onBattery) {
2438        // When plugging in, update the CPU stats first before changing
2439        // the plug state.
2440        updateCpuStatsNow();
2441        synchronized (this) {
2442            synchronized(mPidsSelfLocked) {
2443                mOnBattery = DEBUG_POWER ? true : onBattery;
2444            }
2445        }
2446    }
2447
2448    /**
2449     * Initialize the application bind args. These are passed to each
2450     * process when the bindApplication() IPC is sent to the process. They're
2451     * lazily setup to make sure the services are running when they're asked for.
2452     */
2453    private HashMap<String, IBinder> getCommonServicesLocked() {
2454        if (mAppBindArgs == null) {
2455            mAppBindArgs = new HashMap<String, IBinder>();
2456
2457            // Setup the application init args
2458            mAppBindArgs.put("package", ServiceManager.getService("package"));
2459            mAppBindArgs.put("window", ServiceManager.getService("window"));
2460            mAppBindArgs.put(Context.ALARM_SERVICE,
2461                    ServiceManager.getService(Context.ALARM_SERVICE));
2462        }
2463        return mAppBindArgs;
2464    }
2465
2466    final void setFocusedActivityLocked(ActivityRecord r) {
2467        if (mFocusedActivity != r) {
2468            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2469            mFocusedActivity = r;
2470            if (r.task != null && r.task.voiceInteractor != null) {
2471                startRunningVoiceLocked();
2472            } else {
2473                finishRunningVoiceLocked();
2474            }
2475            mStackSupervisor.setFocusedStack(r);
2476            if (r != null) {
2477                mWindowManager.setFocusedApp(r.appToken, true);
2478            }
2479            applyUpdateLockStateLocked(r);
2480        }
2481    }
2482
2483    final void clearFocusedActivity(ActivityRecord r) {
2484        if (mFocusedActivity == r) {
2485            mFocusedActivity = null;
2486        }
2487    }
2488
2489    @Override
2490    public void setFocusedStack(int stackId) {
2491        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2492        synchronized (ActivityManagerService.this) {
2493            ActivityStack stack = mStackSupervisor.getStack(stackId);
2494            if (stack != null) {
2495                ActivityRecord r = stack.topRunningActivityLocked(null);
2496                if (r != null) {
2497                    setFocusedActivityLocked(r);
2498                }
2499            }
2500        }
2501    }
2502
2503    @Override
2504    public void notifyActivityDrawn(IBinder token) {
2505        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2506        synchronized (this) {
2507            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2508            if (r != null) {
2509                r.task.stack.notifyActivityDrawnLocked(r);
2510            }
2511        }
2512    }
2513
2514    final void applyUpdateLockStateLocked(ActivityRecord r) {
2515        // Modifications to the UpdateLock state are done on our handler, outside
2516        // the activity manager's locks.  The new state is determined based on the
2517        // state *now* of the relevant activity record.  The object is passed to
2518        // the handler solely for logging detail, not to be consulted/modified.
2519        final boolean nextState = r != null && r.immersive;
2520        mHandler.sendMessage(
2521                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2522    }
2523
2524    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2525        Message msg = Message.obtain();
2526        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2527        msg.obj = r.task.askedCompatMode ? null : r;
2528        mHandler.sendMessage(msg);
2529    }
2530
2531    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2532            String what, Object obj, ProcessRecord srcApp) {
2533        app.lastActivityTime = now;
2534
2535        if (app.activities.size() > 0) {
2536            // Don't want to touch dependent processes that are hosting activities.
2537            return index;
2538        }
2539
2540        int lrui = mLruProcesses.lastIndexOf(app);
2541        if (lrui < 0) {
2542            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2543                    + what + " " + obj + " from " + srcApp);
2544            return index;
2545        }
2546
2547        if (lrui >= index) {
2548            // Don't want to cause this to move dependent processes *back* in the
2549            // list as if they were less frequently used.
2550            return index;
2551        }
2552
2553        if (lrui >= mLruProcessActivityStart) {
2554            // Don't want to touch dependent processes that are hosting activities.
2555            return index;
2556        }
2557
2558        mLruProcesses.remove(lrui);
2559        if (index > 0) {
2560            index--;
2561        }
2562        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2563                + " in LRU list: " + app);
2564        mLruProcesses.add(index, app);
2565        return index;
2566    }
2567
2568    final void removeLruProcessLocked(ProcessRecord app) {
2569        int lrui = mLruProcesses.lastIndexOf(app);
2570        if (lrui >= 0) {
2571            if (lrui <= mLruProcessActivityStart) {
2572                mLruProcessActivityStart--;
2573            }
2574            if (lrui <= mLruProcessServiceStart) {
2575                mLruProcessServiceStart--;
2576            }
2577            mLruProcesses.remove(lrui);
2578        }
2579    }
2580
2581    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2582            ProcessRecord client) {
2583        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2584                || app.treatLikeActivity;
2585        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2586        if (!activityChange && hasActivity) {
2587            // The process has activities, so we are only allowing activity-based adjustments
2588            // to move it.  It should be kept in the front of the list with other
2589            // processes that have activities, and we don't want those to change their
2590            // order except due to activity operations.
2591            return;
2592        }
2593
2594        mLruSeq++;
2595        final long now = SystemClock.uptimeMillis();
2596        app.lastActivityTime = now;
2597
2598        // First a quick reject: if the app is already at the position we will
2599        // put it, then there is nothing to do.
2600        if (hasActivity) {
2601            final int N = mLruProcesses.size();
2602            if (N > 0 && mLruProcesses.get(N-1) == app) {
2603                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2604                return;
2605            }
2606        } else {
2607            if (mLruProcessServiceStart > 0
2608                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2609                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2610                return;
2611            }
2612        }
2613
2614        int lrui = mLruProcesses.lastIndexOf(app);
2615
2616        if (app.persistent && lrui >= 0) {
2617            // We don't care about the position of persistent processes, as long as
2618            // they are in the list.
2619            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2620            return;
2621        }
2622
2623        /* In progress: compute new position first, so we can avoid doing work
2624           if the process is not actually going to move.  Not yet working.
2625        int addIndex;
2626        int nextIndex;
2627        boolean inActivity = false, inService = false;
2628        if (hasActivity) {
2629            // Process has activities, put it at the very tipsy-top.
2630            addIndex = mLruProcesses.size();
2631            nextIndex = mLruProcessServiceStart;
2632            inActivity = true;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            addIndex = mLruProcessActivityStart;
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638            inService = true;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            addIndex = mLruProcessServiceStart;
2642            if (client != null) {
2643                int clientIndex = mLruProcesses.lastIndexOf(client);
2644                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2645                        + app);
2646                if (clientIndex >= 0 && addIndex > clientIndex) {
2647                    addIndex = clientIndex;
2648                }
2649            }
2650            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2651        }
2652
2653        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2654                + mLruProcessActivityStart + "): " + app);
2655        */
2656
2657        if (lrui >= 0) {
2658            if (lrui < mLruProcessActivityStart) {
2659                mLruProcessActivityStart--;
2660            }
2661            if (lrui < mLruProcessServiceStart) {
2662                mLruProcessServiceStart--;
2663            }
2664            /*
2665            if (addIndex > lrui) {
2666                addIndex--;
2667            }
2668            if (nextIndex > lrui) {
2669                nextIndex--;
2670            }
2671            */
2672            mLruProcesses.remove(lrui);
2673        }
2674
2675        /*
2676        mLruProcesses.add(addIndex, app);
2677        if (inActivity) {
2678            mLruProcessActivityStart++;
2679        }
2680        if (inService) {
2681            mLruProcessActivityStart++;
2682        }
2683        */
2684
2685        int nextIndex;
2686        if (hasActivity) {
2687            final int N = mLruProcesses.size();
2688            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2689                // Process doesn't have activities, but has clients with
2690                // activities...  move it up, but one below the top (the top
2691                // should always have a real activity).
2692                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2693                mLruProcesses.add(N-1, app);
2694                // To keep it from spamming the LRU list (by making a bunch of clients),
2695                // we will push down any other entries owned by the app.
2696                final int uid = app.info.uid;
2697                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2698                    ProcessRecord subProc = mLruProcesses.get(i);
2699                    if (subProc.info.uid == uid) {
2700                        // We want to push this one down the list.  If the process after
2701                        // it is for the same uid, however, don't do so, because we don't
2702                        // want them internally to be re-ordered.
2703                        if (mLruProcesses.get(i-1).info.uid != uid) {
2704                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2705                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2706                            ProcessRecord tmp = mLruProcesses.get(i);
2707                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2708                            mLruProcesses.set(i-1, tmp);
2709                            i--;
2710                        }
2711                    } else {
2712                        // A gap, we can stop here.
2713                        break;
2714                    }
2715                }
2716            } else {
2717                // Process has activities, put it at the very tipsy-top.
2718                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2719                mLruProcesses.add(app);
2720            }
2721            nextIndex = mLruProcessServiceStart;
2722        } else if (hasService) {
2723            // Process has services, put it at the top of the service list.
2724            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2725            mLruProcesses.add(mLruProcessActivityStart, app);
2726            nextIndex = mLruProcessServiceStart;
2727            mLruProcessActivityStart++;
2728        } else  {
2729            // Process not otherwise of interest, it goes to the top of the non-service area.
2730            int index = mLruProcessServiceStart;
2731            if (client != null) {
2732                // If there is a client, don't allow the process to be moved up higher
2733                // in the list than that client.
2734                int clientIndex = mLruProcesses.lastIndexOf(client);
2735                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2736                        + " when updating " + app);
2737                if (clientIndex <= lrui) {
2738                    // Don't allow the client index restriction to push it down farther in the
2739                    // list than it already is.
2740                    clientIndex = lrui;
2741                }
2742                if (clientIndex >= 0 && index > clientIndex) {
2743                    index = clientIndex;
2744                }
2745            }
2746            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2747            mLruProcesses.add(index, app);
2748            nextIndex = index-1;
2749            mLruProcessActivityStart++;
2750            mLruProcessServiceStart++;
2751        }
2752
2753        // If the app is currently using a content provider or service,
2754        // bump those processes as well.
2755        for (int j=app.connections.size()-1; j>=0; j--) {
2756            ConnectionRecord cr = app.connections.valueAt(j);
2757            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2758                    && cr.binding.service.app != null
2759                    && cr.binding.service.app.lruSeq != mLruSeq
2760                    && !cr.binding.service.app.persistent) {
2761                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2762                        "service connection", cr, app);
2763            }
2764        }
2765        for (int j=app.conProviders.size()-1; j>=0; j--) {
2766            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2767            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2768                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2769                        "provider reference", cpr, app);
2770            }
2771        }
2772    }
2773
2774    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2775        if (uid == Process.SYSTEM_UID) {
2776            // The system gets to run in any process.  If there are multiple
2777            // processes with the same uid, just pick the first (this
2778            // should never happen).
2779            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2780            if (procs == null) return null;
2781            final int N = procs.size();
2782            for (int i = 0; i < N; i++) {
2783                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2784            }
2785        }
2786        ProcessRecord proc = mProcessNames.get(processName, uid);
2787        if (false && proc != null && !keepIfLarge
2788                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2789                && proc.lastCachedPss >= 4000) {
2790            // Turn this condition on to cause killing to happen regularly, for testing.
2791            if (proc.baseProcessTracker != null) {
2792                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2793            }
2794            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2795                    + "k from cached");
2796        } else if (proc != null && !keepIfLarge
2797                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2798                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2799            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2800            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2801                if (proc.baseProcessTracker != null) {
2802                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2803                }
2804                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2805                        + "k from cached");
2806            }
2807        }
2808        return proc;
2809    }
2810
2811    void ensurePackageDexOpt(String packageName) {
2812        IPackageManager pm = AppGlobals.getPackageManager();
2813        try {
2814            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2815                mDidDexOpt = true;
2816            }
2817        } catch (RemoteException e) {
2818        }
2819    }
2820
2821    boolean isNextTransitionForward() {
2822        int transit = mWindowManager.getPendingAppTransition();
2823        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2824                || transit == AppTransition.TRANSIT_TASK_OPEN
2825                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2826    }
2827
2828    final ProcessRecord startProcessLocked(String processName,
2829            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2830            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2831            boolean isolated, boolean keepIfLarge) {
2832        ProcessRecord app;
2833        if (!isolated) {
2834            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2835        } else {
2836            // If this is an isolated process, it can't re-use an existing process.
2837            app = null;
2838        }
2839        // We don't have to do anything more if:
2840        // (1) There is an existing application record; and
2841        // (2) The caller doesn't think it is dead, OR there is no thread
2842        //     object attached to it so we know it couldn't have crashed; and
2843        // (3) There is a pid assigned to it, so it is either starting or
2844        //     already running.
2845        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2846                + " app=" + app + " knownToBeDead=" + knownToBeDead
2847                + " thread=" + (app != null ? app.thread : null)
2848                + " pid=" + (app != null ? app.pid : -1));
2849        if (app != null && app.pid > 0) {
2850            if (!knownToBeDead || app.thread == null) {
2851                // We already have the app running, or are waiting for it to
2852                // come up (we have a pid but not yet its thread), so keep it.
2853                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2854                // If this is a new package in the process, add the package to the list
2855                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2856                return app;
2857            }
2858
2859            // An application record is attached to a previous process,
2860            // clean it up now.
2861            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2862            Process.killProcessGroup(app.info.uid, app.pid);
2863            handleAppDiedLocked(app, true, true);
2864        }
2865
2866        String hostingNameStr = hostingName != null
2867                ? hostingName.flattenToShortString() : null;
2868
2869        if (!isolated) {
2870            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2871                // If we are in the background, then check to see if this process
2872                // is bad.  If so, we will just silently fail.
2873                if (mBadProcesses.get(info.processName, info.uid) != null) {
2874                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2875                            + "/" + info.processName);
2876                    return null;
2877                }
2878            } else {
2879                // When the user is explicitly starting a process, then clear its
2880                // crash count so that we won't make it bad until they see at
2881                // least one crash dialog again, and make the process good again
2882                // if it had been bad.
2883                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2884                        + "/" + info.processName);
2885                mProcessCrashTimes.remove(info.processName, info.uid);
2886                if (mBadProcesses.get(info.processName, info.uid) != null) {
2887                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2888                            UserHandle.getUserId(info.uid), info.uid,
2889                            info.processName);
2890                    mBadProcesses.remove(info.processName, info.uid);
2891                    if (app != null) {
2892                        app.bad = false;
2893                    }
2894                }
2895            }
2896        }
2897
2898        if (app == null) {
2899            app = newProcessRecordLocked(info, processName, isolated);
2900            if (app == null) {
2901                Slog.w(TAG, "Failed making new process record for "
2902                        + processName + "/" + info.uid + " isolated=" + isolated);
2903                return null;
2904            }
2905            mProcessNames.put(processName, app.uid, app);
2906            if (isolated) {
2907                mIsolatedProcesses.put(app.uid, app);
2908            }
2909        } else {
2910            // If this is a new package in the process, add the package to the list
2911            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2912        }
2913
2914        // If the system is not ready yet, then hold off on starting this
2915        // process until it is.
2916        if (!mProcessesReady
2917                && !isAllowedWhileBooting(info)
2918                && !allowWhileBooting) {
2919            if (!mProcessesOnHold.contains(app)) {
2920                mProcessesOnHold.add(app);
2921            }
2922            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2923            return app;
2924        }
2925
2926        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2927        return (app.pid != 0) ? app : null;
2928    }
2929
2930    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2931        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2932    }
2933
2934    private final void startProcessLocked(ProcessRecord app,
2935            String hostingType, String hostingNameStr, String abiOverride) {
2936        if (app.pid > 0 && app.pid != MY_PID) {
2937            synchronized (mPidsSelfLocked) {
2938                mPidsSelfLocked.remove(app.pid);
2939                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2940            }
2941            app.setPid(0);
2942        }
2943
2944        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2945                "startProcessLocked removing on hold: " + app);
2946        mProcessesOnHold.remove(app);
2947
2948        updateCpuStats();
2949
2950        try {
2951            int uid = app.uid;
2952
2953            int[] gids = null;
2954            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2955            if (!app.isolated) {
2956                int[] permGids = null;
2957                try {
2958                    final PackageManager pm = mContext.getPackageManager();
2959                    permGids = pm.getPackageGids(app.info.packageName);
2960
2961                    if (Environment.isExternalStorageEmulated()) {
2962                        if (pm.checkPermission(
2963                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2964                                app.info.packageName) == PERMISSION_GRANTED) {
2965                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2966                        } else {
2967                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2968                        }
2969                    }
2970                } catch (PackageManager.NameNotFoundException e) {
2971                    Slog.w(TAG, "Unable to retrieve gids", e);
2972                }
2973
2974                /*
2975                 * Add shared application and profile GIDs so applications can share some
2976                 * resources like shared libraries and access user-wide resources
2977                 */
2978                if (permGids == null) {
2979                    gids = new int[2];
2980                } else {
2981                    gids = new int[permGids.length + 2];
2982                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2983                }
2984                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2985                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2986            }
2987            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2988                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2989                        && mTopComponent != null
2990                        && app.processName.equals(mTopComponent.getPackageName())) {
2991                    uid = 0;
2992                }
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2994                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2995                    uid = 0;
2996                }
2997            }
2998            int debugFlags = 0;
2999            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3000                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3001                // Also turn on CheckJNI for debuggable apps. It's quite
3002                // awkward to turn on otherwise.
3003                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3004            }
3005            // Run the app in safe mode if its manifest requests so or the
3006            // system is booted in safe mode.
3007            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3008                mSafeMode == true) {
3009                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3010            }
3011            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3012                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3013            }
3014            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3015                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3016            }
3017            if ("1".equals(SystemProperties.get("debug.assert"))) {
3018                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3019            }
3020
3021            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3022            if (requiredAbi == null) {
3023                requiredAbi = Build.SUPPORTED_ABIS[0];
3024            }
3025
3026            // Start the process.  It will either succeed and return a result containing
3027            // the PID of the new process, or else throw a RuntimeException.
3028            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3029                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3030                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3031
3032            if (app.isolated) {
3033                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3034            }
3035            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3036
3037            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3038                    UserHandle.getUserId(uid), startResult.pid, uid,
3039                    app.processName, hostingType,
3040                    hostingNameStr != null ? hostingNameStr : "");
3041
3042            if (app.persistent) {
3043                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3044            }
3045
3046            StringBuilder buf = mStringBuilder;
3047            buf.setLength(0);
3048            buf.append("Start proc ");
3049            buf.append(app.processName);
3050            buf.append(" for ");
3051            buf.append(hostingType);
3052            if (hostingNameStr != null) {
3053                buf.append(" ");
3054                buf.append(hostingNameStr);
3055            }
3056            buf.append(": pid=");
3057            buf.append(startResult.pid);
3058            buf.append(" uid=");
3059            buf.append(uid);
3060            buf.append(" gids={");
3061            if (gids != null) {
3062                for (int gi=0; gi<gids.length; gi++) {
3063                    if (gi != 0) buf.append(", ");
3064                    buf.append(gids[gi]);
3065
3066                }
3067            }
3068            buf.append("}");
3069            if (requiredAbi != null) {
3070                buf.append(" abi=");
3071                buf.append(requiredAbi);
3072            }
3073            Slog.i(TAG, buf.toString());
3074            app.setPid(startResult.pid);
3075            app.usingWrapper = startResult.usingWrapper;
3076            app.removed = false;
3077            app.killedByAm = false;
3078            synchronized (mPidsSelfLocked) {
3079                this.mPidsSelfLocked.put(startResult.pid, app);
3080                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3081                msg.obj = app;
3082                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3083                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3084            }
3085        } catch (RuntimeException e) {
3086            // XXX do better error recovery.
3087            app.setPid(0);
3088            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3089            if (app.isolated) {
3090                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3091            }
3092            Slog.e(TAG, "Failure starting process " + app.processName, e);
3093        }
3094    }
3095
3096    void updateUsageStats(ActivityRecord component, boolean resumed) {
3097        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3098        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3099        if (resumed) {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3102                        System.currentTimeMillis(),
3103                        UsageStats.Event.MOVE_TO_FOREGROUND);
3104            }
3105            synchronized (stats) {
3106                stats.noteActivityResumedLocked(component.app.uid);
3107            }
3108        } else {
3109            if (mUsageStatsService != null) {
3110                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3111                        System.currentTimeMillis(),
3112                        UsageStats.Event.MOVE_TO_BACKGROUND);
3113            }
3114            synchronized (stats) {
3115                stats.noteActivityPausedLocked(component.app.uid);
3116            }
3117        }
3118    }
3119
3120    Intent getHomeIntent() {
3121        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3122        intent.setComponent(mTopComponent);
3123        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3124            intent.addCategory(Intent.CATEGORY_HOME);
3125        }
3126        return intent;
3127    }
3128
3129    boolean startHomeActivityLocked(int userId) {
3130        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3131                && mTopAction == null) {
3132            // We are running in factory test mode, but unable to find
3133            // the factory test app, so just sit around displaying the
3134            // error message and don't try to start anything.
3135            return false;
3136        }
3137        Intent intent = getHomeIntent();
3138        ActivityInfo aInfo =
3139            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3140        if (aInfo != null) {
3141            intent.setComponent(new ComponentName(
3142                    aInfo.applicationInfo.packageName, aInfo.name));
3143            // Don't do this if the home app is currently being
3144            // instrumented.
3145            aInfo = new ActivityInfo(aInfo);
3146            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3147            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3148                    aInfo.applicationInfo.uid, true);
3149            if (app == null || app.instrumentationClass == null) {
3150                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3151                mStackSupervisor.startHomeActivity(intent, aInfo);
3152            }
3153        }
3154
3155        return true;
3156    }
3157
3158    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3159        ActivityInfo ai = null;
3160        ComponentName comp = intent.getComponent();
3161        try {
3162            if (comp != null) {
3163                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3164            } else {
3165                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3166                        intent,
3167                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3168                            flags, userId);
3169
3170                if (info != null) {
3171                    ai = info.activityInfo;
3172                }
3173            }
3174        } catch (RemoteException e) {
3175            // ignore
3176        }
3177
3178        return ai;
3179    }
3180
3181    /**
3182     * Starts the "new version setup screen" if appropriate.
3183     */
3184    void startSetupActivityLocked() {
3185        // Only do this once per boot.
3186        if (mCheckedForSetup) {
3187            return;
3188        }
3189
3190        // We will show this screen if the current one is a different
3191        // version than the last one shown, and we are not running in
3192        // low-level factory test mode.
3193        final ContentResolver resolver = mContext.getContentResolver();
3194        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3195                Settings.Global.getInt(resolver,
3196                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3197            mCheckedForSetup = true;
3198
3199            // See if we should be showing the platform update setup UI.
3200            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3201            List<ResolveInfo> ris = mContext.getPackageManager()
3202                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3203
3204            // We don't allow third party apps to replace this.
3205            ResolveInfo ri = null;
3206            for (int i=0; ris != null && i<ris.size(); i++) {
3207                if ((ris.get(i).activityInfo.applicationInfo.flags
3208                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3209                    ri = ris.get(i);
3210                    break;
3211                }
3212            }
3213
3214            if (ri != null) {
3215                String vers = ri.activityInfo.metaData != null
3216                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3217                        : null;
3218                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3219                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3220                            Intent.METADATA_SETUP_VERSION);
3221                }
3222                String lastVers = Settings.Secure.getString(
3223                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3224                if (vers != null && !vers.equals(lastVers)) {
3225                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3226                    intent.setComponent(new ComponentName(
3227                            ri.activityInfo.packageName, ri.activityInfo.name));
3228                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3229                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3230                }
3231            }
3232        }
3233    }
3234
3235    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3236        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3237    }
3238
3239    void enforceNotIsolatedCaller(String caller) {
3240        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3241            throw new SecurityException("Isolated process not allowed to call " + caller);
3242        }
3243    }
3244
3245    @Override
3246    public int getFrontActivityScreenCompatMode() {
3247        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3248        synchronized (this) {
3249            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3250        }
3251    }
3252
3253    @Override
3254    public void setFrontActivityScreenCompatMode(int mode) {
3255        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3256                "setFrontActivityScreenCompatMode");
3257        synchronized (this) {
3258            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3259        }
3260    }
3261
3262    @Override
3263    public int getPackageScreenCompatMode(String packageName) {
3264        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3265        synchronized (this) {
3266            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3267        }
3268    }
3269
3270    @Override
3271    public void setPackageScreenCompatMode(String packageName, int mode) {
3272        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3273                "setPackageScreenCompatMode");
3274        synchronized (this) {
3275            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3276        }
3277    }
3278
3279    @Override
3280    public boolean getPackageAskScreenCompat(String packageName) {
3281        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3282        synchronized (this) {
3283            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3284        }
3285    }
3286
3287    @Override
3288    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3289        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3290                "setPackageAskScreenCompat");
3291        synchronized (this) {
3292            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3293        }
3294    }
3295
3296    private void dispatchProcessesChanged() {
3297        int N;
3298        synchronized (this) {
3299            N = mPendingProcessChanges.size();
3300            if (mActiveProcessChanges.length < N) {
3301                mActiveProcessChanges = new ProcessChangeItem[N];
3302            }
3303            mPendingProcessChanges.toArray(mActiveProcessChanges);
3304            mAvailProcessChanges.addAll(mPendingProcessChanges);
3305            mPendingProcessChanges.clear();
3306            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3307        }
3308
3309        int i = mProcessObservers.beginBroadcast();
3310        while (i > 0) {
3311            i--;
3312            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3313            if (observer != null) {
3314                try {
3315                    for (int j=0; j<N; j++) {
3316                        ProcessChangeItem item = mActiveProcessChanges[j];
3317                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3318                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3319                                    + item.pid + " uid=" + item.uid + ": "
3320                                    + item.foregroundActivities);
3321                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3322                                    item.foregroundActivities);
3323                        }
3324                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3325                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3326                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3327                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3328                        }
3329                    }
3330                } catch (RemoteException e) {
3331                }
3332            }
3333        }
3334        mProcessObservers.finishBroadcast();
3335    }
3336
3337    private void dispatchProcessDied(int pid, int uid) {
3338        int i = mProcessObservers.beginBroadcast();
3339        while (i > 0) {
3340            i--;
3341            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3342            if (observer != null) {
3343                try {
3344                    observer.onProcessDied(pid, uid);
3345                } catch (RemoteException e) {
3346                }
3347            }
3348        }
3349        mProcessObservers.finishBroadcast();
3350    }
3351
3352    @Override
3353    public final int startActivity(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo,
3355            String resultWho, int requestCode, int startFlags,
3356            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3357        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3358                resultWho, requestCode,
3359                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3360    }
3361
3362    @Override
3363    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo,
3365            String resultWho, int requestCode, int startFlags,
3366            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3367        enforceNotIsolatedCaller("startActivity");
3368        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3369                false, ALLOW_FULL_ONLY, "startActivity", null);
3370        // TODO: Switch to user app stacks here.
3371        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3372                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3373                null, null, options, userId, null);
3374    }
3375
3376    @Override
3377    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3378            Intent intent, String resolvedType, IBinder resultTo,
3379            String resultWho, int requestCode, int startFlags, String profileFile,
3380            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3381        enforceNotIsolatedCaller("startActivityAndWait");
3382        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3383                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3384        WaitResult res = new WaitResult();
3385        // TODO: Switch to user app stacks here.
3386        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3387                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3388                res, null, options, userId, null);
3389        return res;
3390    }
3391
3392    @Override
3393    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3394            Intent intent, String resolvedType, IBinder resultTo,
3395            String resultWho, int requestCode, int startFlags, Configuration config,
3396            Bundle options, int userId) {
3397        enforceNotIsolatedCaller("startActivityWithConfig");
3398        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3399                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3400        // TODO: Switch to user app stacks here.
3401        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3402                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3403                null, null, null, config, options, userId, null);
3404        return ret;
3405    }
3406
3407    @Override
3408    public int startActivityIntentSender(IApplicationThread caller,
3409            IntentSender intent, Intent fillInIntent, String resolvedType,
3410            IBinder resultTo, String resultWho, int requestCode,
3411            int flagsMask, int flagsValues, Bundle options) {
3412        enforceNotIsolatedCaller("startActivityIntentSender");
3413        // Refuse possible leaked file descriptors
3414        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3415            throw new IllegalArgumentException("File descriptors passed in Intent");
3416        }
3417
3418        IIntentSender sender = intent.getTarget();
3419        if (!(sender instanceof PendingIntentRecord)) {
3420            throw new IllegalArgumentException("Bad PendingIntent object");
3421        }
3422
3423        PendingIntentRecord pir = (PendingIntentRecord)sender;
3424
3425        synchronized (this) {
3426            // If this is coming from the currently resumed activity, it is
3427            // effectively saying that app switches are allowed at this point.
3428            final ActivityStack stack = getFocusedStack();
3429            if (stack.mResumedActivity != null &&
3430                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3431                mAppSwitchesAllowedTime = 0;
3432            }
3433        }
3434        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3435                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3436        return ret;
3437    }
3438
3439    @Override
3440    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3441            Intent intent, String resolvedType, IVoiceInteractionSession session,
3442            IVoiceInteractor interactor, int startFlags, String profileFile,
3443            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3444        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3445                != PackageManager.PERMISSION_GRANTED) {
3446            String msg = "Permission Denial: startVoiceActivity() from pid="
3447                    + Binder.getCallingPid()
3448                    + ", uid=" + Binder.getCallingUid()
3449                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3450            Slog.w(TAG, msg);
3451            throw new SecurityException(msg);
3452        }
3453        if (session == null || interactor == null) {
3454            throw new NullPointerException("null session or interactor");
3455        }
3456        userId = handleIncomingUser(callingPid, callingUid, userId,
3457                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3458        // TODO: Switch to user app stacks here.
3459        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3460                resolvedType, session, interactor, null, null, 0, startFlags,
3461                profileFile, profileFd, null, null, options, userId, null);
3462    }
3463
3464    @Override
3465    public boolean startNextMatchingActivity(IBinder callingActivity,
3466            Intent intent, Bundle options) {
3467        // Refuse possible leaked file descriptors
3468        if (intent != null && intent.hasFileDescriptors() == true) {
3469            throw new IllegalArgumentException("File descriptors passed in Intent");
3470        }
3471
3472        synchronized (this) {
3473            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3474            if (r == null) {
3475                ActivityOptions.abort(options);
3476                return false;
3477            }
3478            if (r.app == null || r.app.thread == null) {
3479                // The caller is not running...  d'oh!
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            intent = new Intent(intent);
3484            // The caller is not allowed to change the data.
3485            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3486            // And we are resetting to find the next component...
3487            intent.setComponent(null);
3488
3489            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3490
3491            ActivityInfo aInfo = null;
3492            try {
3493                List<ResolveInfo> resolves =
3494                    AppGlobals.getPackageManager().queryIntentActivities(
3495                            intent, r.resolvedType,
3496                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3497                            UserHandle.getCallingUserId());
3498
3499                // Look for the original activity in the list...
3500                final int N = resolves != null ? resolves.size() : 0;
3501                for (int i=0; i<N; i++) {
3502                    ResolveInfo rInfo = resolves.get(i);
3503                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3504                            && rInfo.activityInfo.name.equals(r.info.name)) {
3505                        // We found the current one...  the next matching is
3506                        // after it.
3507                        i++;
3508                        if (i<N) {
3509                            aInfo = resolves.get(i).activityInfo;
3510                        }
3511                        if (debug) {
3512                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3513                                    + "/" + r.info.name);
3514                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3515                                    + "/" + aInfo.name);
3516                        }
3517                        break;
3518                    }
3519                }
3520            } catch (RemoteException e) {
3521            }
3522
3523            if (aInfo == null) {
3524                // Nobody who is next!
3525                ActivityOptions.abort(options);
3526                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3527                return false;
3528            }
3529
3530            intent.setComponent(new ComponentName(
3531                    aInfo.applicationInfo.packageName, aInfo.name));
3532            intent.setFlags(intent.getFlags()&~(
3533                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3534                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3535                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3536                    Intent.FLAG_ACTIVITY_NEW_TASK));
3537
3538            // Okay now we need to start the new activity, replacing the
3539            // currently running activity.  This is a little tricky because
3540            // we want to start the new one as if the current one is finished,
3541            // but not finish the current one first so that there is no flicker.
3542            // And thus...
3543            final boolean wasFinishing = r.finishing;
3544            r.finishing = true;
3545
3546            // Propagate reply information over to the new activity.
3547            final ActivityRecord resultTo = r.resultTo;
3548            final String resultWho = r.resultWho;
3549            final int requestCode = r.requestCode;
3550            r.resultTo = null;
3551            if (resultTo != null) {
3552                resultTo.removeResultsLocked(r, resultWho, requestCode);
3553            }
3554
3555            final long origId = Binder.clearCallingIdentity();
3556            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3557                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3558                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3559                    options, false, null, null);
3560            Binder.restoreCallingIdentity(origId);
3561
3562            r.finishing = wasFinishing;
3563            if (res != ActivityManager.START_SUCCESS) {
3564                return false;
3565            }
3566            return true;
3567        }
3568    }
3569
3570    @Override
3571    public final int startActivityFromRecents(int taskId, Bundle options) {
3572        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3573            String msg = "Permission Denial: startActivityFromRecents called without " +
3574                    START_TASKS_FROM_RECENTS;
3575            Slog.w(TAG, msg);
3576            throw new SecurityException(msg);
3577        }
3578        final int callingUid;
3579        final String callingPackage;
3580        final Intent intent;
3581        final int userId;
3582        synchronized (this) {
3583            final TaskRecord task = recentTaskForIdLocked(taskId);
3584            if (task == null) {
3585                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3586            }
3587            callingUid = task.mCallingUid;
3588            callingPackage = task.mCallingPackage;
3589            intent = task.intent;
3590            userId = task.userId;
3591        }
3592        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3593                options, userId, null);
3594    }
3595
3596    final int startActivityInPackage(int uid, String callingPackage,
3597            Intent intent, String resolvedType, IBinder resultTo,
3598            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3599                    IActivityContainer container) {
3600
3601        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3602                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3603
3604        // TODO: Switch to user app stacks here.
3605        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3606                null, null, resultTo, resultWho, requestCode, startFlags,
3607                null, null, null, null, options, userId, container);
3608        return ret;
3609    }
3610
3611    @Override
3612    public final int startActivities(IApplicationThread caller, String callingPackage,
3613            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3614            int userId) {
3615        enforceNotIsolatedCaller("startActivities");
3616        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3617                false, ALLOW_FULL_ONLY, "startActivity", null);
3618        // TODO: Switch to user app stacks here.
3619        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3620                resolvedTypes, resultTo, options, userId);
3621        return ret;
3622    }
3623
3624    final int startActivitiesInPackage(int uid, String callingPackage,
3625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3626            Bundle options, int userId) {
3627
3628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3629                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3630        // TODO: Switch to user app stacks here.
3631        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3632                resultTo, options, userId);
3633        return ret;
3634    }
3635
3636    final void addRecentTaskLocked(TaskRecord task) {
3637        int N = mRecentTasks.size();
3638        // Quick case: check if the top-most recent task is the same.
3639        if (N > 0 && mRecentTasks.get(0) == task) {
3640            return;
3641        }
3642        // Another quick case: never add voice sessions.
3643        if (task.voiceSession != null) {
3644            return;
3645        }
3646        // Remove any existing entries that are the same kind of task.
3647        final Intent intent = task.intent;
3648        final boolean document = intent != null && intent.isDocument();
3649        final ComponentName comp = intent.getComponent();
3650
3651        int maxRecents = task.maxRecents - 1;
3652        for (int i=0; i<N; i++) {
3653            final TaskRecord tr = mRecentTasks.get(i);
3654            if (task != tr) {
3655                if (task.userId != tr.userId) {
3656                    continue;
3657                }
3658                if (i > MAX_RECENT_BITMAPS) {
3659                    tr.freeLastThumbnail();
3660                }
3661                final Intent trIntent = tr.intent;
3662                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3663                    (intent == null || !intent.filterEquals(trIntent))) {
3664                    continue;
3665                }
3666                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3667                if (document && trIsDocument) {
3668                    // These are the same document activity (not necessarily the same doc).
3669                    if (maxRecents > 0) {
3670                        --maxRecents;
3671                        continue;
3672                    }
3673                    // Hit the maximum number of documents for this task. Fall through
3674                    // and remove this document from recents.
3675                } else if (document || trIsDocument) {
3676                    // Only one of these is a document. Not the droid we're looking for.
3677                    continue;
3678                }
3679            }
3680
3681            // Either task and tr are the same or, their affinities match or their intents match
3682            // and neither of them is a document, or they are documents using the same activity
3683            // and their maxRecents has been reached.
3684            tr.disposeThumbnail();
3685            mRecentTasks.remove(i);
3686            if (task != tr) {
3687                tr.closeRecentsChain();
3688            }
3689            i--;
3690            N--;
3691            if (task.intent == null) {
3692                // If the new recent task we are adding is not fully
3693                // specified, then replace it with the existing recent task.
3694                task = tr;
3695            }
3696            mTaskPersister.notify(tr, false);
3697        }
3698        if (N >= MAX_RECENT_TASKS) {
3699            final TaskRecord tr = mRecentTasks.remove(N - 1);
3700            tr.disposeThumbnail();
3701            tr.closeRecentsChain();
3702        }
3703        mRecentTasks.add(0, task);
3704    }
3705
3706    @Override
3707    public void reportActivityFullyDrawn(IBinder token) {
3708        synchronized (this) {
3709            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3710            if (r == null) {
3711                return;
3712            }
3713            r.reportFullyDrawnLocked();
3714        }
3715    }
3716
3717    @Override
3718    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3719        synchronized (this) {
3720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3721            if (r == null) {
3722                return;
3723            }
3724            final long origId = Binder.clearCallingIdentity();
3725            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3726            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3727                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3728            if (config != null) {
3729                r.frozenBeforeDestroy = true;
3730                if (!updateConfigurationLocked(config, r, false, false)) {
3731                    mStackSupervisor.resumeTopActivitiesLocked();
3732                }
3733            }
3734            Binder.restoreCallingIdentity(origId);
3735        }
3736    }
3737
3738    @Override
3739    public int getRequestedOrientation(IBinder token) {
3740        synchronized (this) {
3741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3742            if (r == null) {
3743                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3744            }
3745            return mWindowManager.getAppOrientation(r.appToken);
3746        }
3747    }
3748
3749    /**
3750     * This is the internal entry point for handling Activity.finish().
3751     *
3752     * @param token The Binder token referencing the Activity we want to finish.
3753     * @param resultCode Result code, if any, from this Activity.
3754     * @param resultData Result data (Intent), if any, from this Activity.
3755     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3756     *            the root Activity in the task.
3757     *
3758     * @return Returns true if the activity successfully finished, or false if it is still running.
3759     */
3760    @Override
3761    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3762            boolean finishTask) {
3763        // Refuse possible leaked file descriptors
3764        if (resultData != null && resultData.hasFileDescriptors() == true) {
3765            throw new IllegalArgumentException("File descriptors passed in Intent");
3766        }
3767
3768        synchronized(this) {
3769            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3770            if (r == null) {
3771                return true;
3772            }
3773            // Keep track of the root activity of the task before we finish it
3774            TaskRecord tr = r.task;
3775            ActivityRecord rootR = tr.getRootActivity();
3776            // Do not allow task to finish in Lock Task mode.
3777            if (tr == mStackSupervisor.mLockTaskModeTask) {
3778                if (rootR == r) {
3779                    mStackSupervisor.showLockTaskToast();
3780                    return false;
3781                }
3782            }
3783            if (mController != null) {
3784                // Find the first activity that is not finishing.
3785                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3786                if (next != null) {
3787                    // ask watcher if this is allowed
3788                    boolean resumeOK = true;
3789                    try {
3790                        resumeOK = mController.activityResuming(next.packageName);
3791                    } catch (RemoteException e) {
3792                        mController = null;
3793                        Watchdog.getInstance().setActivityController(null);
3794                    }
3795
3796                    if (!resumeOK) {
3797                        return false;
3798                    }
3799                }
3800            }
3801            final long origId = Binder.clearCallingIdentity();
3802            try {
3803                boolean res;
3804                if (finishTask && r == rootR) {
3805                    // If requested, remove the task that is associated to this activity only if it
3806                    // was the root activity in the task.  The result code and data is ignored because
3807                    // we don't support returning them across task boundaries.
3808                    res = removeTaskByIdLocked(tr.taskId, 0);
3809                } else {
3810                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3811                            resultData, "app-request", true);
3812                }
3813                return res;
3814            } finally {
3815                Binder.restoreCallingIdentity(origId);
3816            }
3817        }
3818    }
3819
3820    @Override
3821    public final void finishHeavyWeightApp() {
3822        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3823                != PackageManager.PERMISSION_GRANTED) {
3824            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3825                    + Binder.getCallingPid()
3826                    + ", uid=" + Binder.getCallingUid()
3827                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3828            Slog.w(TAG, msg);
3829            throw new SecurityException(msg);
3830        }
3831
3832        synchronized(this) {
3833            if (mHeavyWeightProcess == null) {
3834                return;
3835            }
3836
3837            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3838                    mHeavyWeightProcess.activities);
3839            for (int i=0; i<activities.size(); i++) {
3840                ActivityRecord r = activities.get(i);
3841                if (!r.finishing) {
3842                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3843                            null, "finish-heavy", true);
3844                }
3845            }
3846
3847            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3848                    mHeavyWeightProcess.userId, 0));
3849            mHeavyWeightProcess = null;
3850        }
3851    }
3852
3853    @Override
3854    public void crashApplication(int uid, int initialPid, String packageName,
3855            String message) {
3856        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3857                != PackageManager.PERMISSION_GRANTED) {
3858            String msg = "Permission Denial: crashApplication() from pid="
3859                    + Binder.getCallingPid()
3860                    + ", uid=" + Binder.getCallingUid()
3861                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3862            Slog.w(TAG, msg);
3863            throw new SecurityException(msg);
3864        }
3865
3866        synchronized(this) {
3867            ProcessRecord proc = null;
3868
3869            // Figure out which process to kill.  We don't trust that initialPid
3870            // still has any relation to current pids, so must scan through the
3871            // list.
3872            synchronized (mPidsSelfLocked) {
3873                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3874                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3875                    if (p.uid != uid) {
3876                        continue;
3877                    }
3878                    if (p.pid == initialPid) {
3879                        proc = p;
3880                        break;
3881                    }
3882                    if (p.pkgList.containsKey(packageName)) {
3883                        proc = p;
3884                    }
3885                }
3886            }
3887
3888            if (proc == null) {
3889                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3890                        + " initialPid=" + initialPid
3891                        + " packageName=" + packageName);
3892                return;
3893            }
3894
3895            if (proc.thread != null) {
3896                if (proc.pid == Process.myPid()) {
3897                    Log.w(TAG, "crashApplication: trying to crash self!");
3898                    return;
3899                }
3900                long ident = Binder.clearCallingIdentity();
3901                try {
3902                    proc.thread.scheduleCrash(message);
3903                } catch (RemoteException e) {
3904                }
3905                Binder.restoreCallingIdentity(ident);
3906            }
3907        }
3908    }
3909
3910    @Override
3911    public final void finishSubActivity(IBinder token, String resultWho,
3912            int requestCode) {
3913        synchronized(this) {
3914            final long origId = Binder.clearCallingIdentity();
3915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3916            if (r != null) {
3917                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3918            }
3919            Binder.restoreCallingIdentity(origId);
3920        }
3921    }
3922
3923    @Override
3924    public boolean finishActivityAffinity(IBinder token) {
3925        synchronized(this) {
3926            final long origId = Binder.clearCallingIdentity();
3927            try {
3928                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3929
3930                ActivityRecord rootR = r.task.getRootActivity();
3931                // Do not allow task to finish in Lock Task mode.
3932                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3933                    if (rootR == r) {
3934                        mStackSupervisor.showLockTaskToast();
3935                        return false;
3936                    }
3937                }
3938                boolean res = false;
3939                if (r != null) {
3940                    res = r.task.stack.finishActivityAffinityLocked(r);
3941                }
3942                return res;
3943            } finally {
3944                Binder.restoreCallingIdentity(origId);
3945            }
3946        }
3947    }
3948
3949    @Override
3950    public void finishVoiceTask(IVoiceInteractionSession session) {
3951        synchronized(this) {
3952            final long origId = Binder.clearCallingIdentity();
3953            try {
3954                mStackSupervisor.finishVoiceTask(session);
3955            } finally {
3956                Binder.restoreCallingIdentity(origId);
3957            }
3958        }
3959
3960    }
3961
3962    @Override
3963    public boolean willActivityBeVisible(IBinder token) {
3964        synchronized(this) {
3965            ActivityStack stack = ActivityRecord.getStackLocked(token);
3966            if (stack != null) {
3967                return stack.willActivityBeVisibleLocked(token);
3968            }
3969            return false;
3970        }
3971    }
3972
3973    @Override
3974    public void overridePendingTransition(IBinder token, String packageName,
3975            int enterAnim, int exitAnim) {
3976        synchronized(this) {
3977            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3978            if (self == null) {
3979                return;
3980            }
3981
3982            final long origId = Binder.clearCallingIdentity();
3983
3984            if (self.state == ActivityState.RESUMED
3985                    || self.state == ActivityState.PAUSING) {
3986                mWindowManager.overridePendingAppTransition(packageName,
3987                        enterAnim, exitAnim, null);
3988            }
3989
3990            Binder.restoreCallingIdentity(origId);
3991        }
3992    }
3993
3994    /**
3995     * Main function for removing an existing process from the activity manager
3996     * as a result of that process going away.  Clears out all connections
3997     * to the process.
3998     */
3999    private final void handleAppDiedLocked(ProcessRecord app,
4000            boolean restarting, boolean allowRestart) {
4001        int pid = app.pid;
4002        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4003        if (!restarting) {
4004            removeLruProcessLocked(app);
4005            if (pid > 0) {
4006                ProcessList.remove(pid);
4007            }
4008        }
4009
4010        if (mProfileProc == app) {
4011            clearProfilerLocked();
4012        }
4013
4014        // Remove this application's activities from active lists.
4015        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4016
4017        app.activities.clear();
4018
4019        if (app.instrumentationClass != null) {
4020            Slog.w(TAG, "Crash of app " + app.processName
4021                  + " running instrumentation " + app.instrumentationClass);
4022            Bundle info = new Bundle();
4023            info.putString("shortMsg", "Process crashed.");
4024            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4025        }
4026
4027        if (!restarting) {
4028            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4029                // If there was nothing to resume, and we are not already
4030                // restarting this process, but there is a visible activity that
4031                // is hosted by the process...  then make sure all visible
4032                // activities are running, taking care of restarting this
4033                // process.
4034                if (hasVisibleActivities) {
4035                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4036                }
4037            }
4038        }
4039    }
4040
4041    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4042        IBinder threadBinder = thread.asBinder();
4043        // Find the application record.
4044        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4045            ProcessRecord rec = mLruProcesses.get(i);
4046            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4047                return i;
4048            }
4049        }
4050        return -1;
4051    }
4052
4053    final ProcessRecord getRecordForAppLocked(
4054            IApplicationThread thread) {
4055        if (thread == null) {
4056            return null;
4057        }
4058
4059        int appIndex = getLRURecordIndexForAppLocked(thread);
4060        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4061    }
4062
4063    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4064        // If there are no longer any background processes running,
4065        // and the app that died was not running instrumentation,
4066        // then tell everyone we are now low on memory.
4067        boolean haveBg = false;
4068        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4069            ProcessRecord rec = mLruProcesses.get(i);
4070            if (rec.thread != null
4071                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4072                haveBg = true;
4073                break;
4074            }
4075        }
4076
4077        if (!haveBg) {
4078            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4079            if (doReport) {
4080                long now = SystemClock.uptimeMillis();
4081                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4082                    doReport = false;
4083                } else {
4084                    mLastMemUsageReportTime = now;
4085                }
4086            }
4087            final ArrayList<ProcessMemInfo> memInfos
4088                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4089            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4090            long now = SystemClock.uptimeMillis();
4091            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4092                ProcessRecord rec = mLruProcesses.get(i);
4093                if (rec == dyingProc || rec.thread == null) {
4094                    continue;
4095                }
4096                if (doReport) {
4097                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4098                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4099                }
4100                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4101                    // The low memory report is overriding any current
4102                    // state for a GC request.  Make sure to do
4103                    // heavy/important/visible/foreground processes first.
4104                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4105                        rec.lastRequestedGc = 0;
4106                    } else {
4107                        rec.lastRequestedGc = rec.lastLowMemory;
4108                    }
4109                    rec.reportLowMemory = true;
4110                    rec.lastLowMemory = now;
4111                    mProcessesToGc.remove(rec);
4112                    addProcessToGcListLocked(rec);
4113                }
4114            }
4115            if (doReport) {
4116                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4117                mHandler.sendMessage(msg);
4118            }
4119            scheduleAppGcsLocked();
4120        }
4121    }
4122
4123    final void appDiedLocked(ProcessRecord app, int pid,
4124            IApplicationThread thread) {
4125
4126        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4127        synchronized (stats) {
4128            stats.noteProcessDiedLocked(app.info.uid, pid);
4129        }
4130
4131        Process.killProcessGroup(app.info.uid, pid);
4132
4133        // Clean up already done if the process has been re-started.
4134        if (app.pid == pid && app.thread != null &&
4135                app.thread.asBinder() == thread.asBinder()) {
4136            boolean doLowMem = app.instrumentationClass == null;
4137            boolean doOomAdj = doLowMem;
4138            if (!app.killedByAm) {
4139                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4140                        + ") has died.");
4141                mAllowLowerMemLevel = true;
4142            } else {
4143                // Note that we always want to do oom adj to update our state with the
4144                // new number of procs.
4145                mAllowLowerMemLevel = false;
4146                doLowMem = false;
4147            }
4148            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4149            if (DEBUG_CLEANUP) Slog.v(
4150                TAG, "Dying app: " + app + ", pid: " + pid
4151                + ", thread: " + thread.asBinder());
4152            handleAppDiedLocked(app, false, true);
4153
4154            if (doOomAdj) {
4155                updateOomAdjLocked();
4156            }
4157            if (doLowMem) {
4158                doLowMemReportIfNeededLocked(app);
4159            }
4160        } else if (app.pid != pid) {
4161            // A new process has already been started.
4162            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4163                    + ") has died and restarted (pid " + app.pid + ").");
4164            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4165        } else if (DEBUG_PROCESSES) {
4166            Slog.d(TAG, "Received spurious death notification for thread "
4167                    + thread.asBinder());
4168        }
4169    }
4170
4171    /**
4172     * If a stack trace dump file is configured, dump process stack traces.
4173     * @param clearTraces causes the dump file to be erased prior to the new
4174     *    traces being written, if true; when false, the new traces will be
4175     *    appended to any existing file content.
4176     * @param firstPids of dalvik VM processes to dump stack traces for first
4177     * @param lastPids of dalvik VM processes to dump stack traces for last
4178     * @param nativeProcs optional list of native process names to dump stack crawls
4179     * @return file containing stack traces, or null if no dump file is configured
4180     */
4181    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4182            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4183        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4184        if (tracesPath == null || tracesPath.length() == 0) {
4185            return null;
4186        }
4187
4188        File tracesFile = new File(tracesPath);
4189        try {
4190            File tracesDir = tracesFile.getParentFile();
4191            if (!tracesDir.exists()) {
4192                tracesFile.mkdirs();
4193                if (!SELinux.restorecon(tracesDir)) {
4194                    return null;
4195                }
4196            }
4197            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4198
4199            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4200            tracesFile.createNewFile();
4201            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4202        } catch (IOException e) {
4203            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4204            return null;
4205        }
4206
4207        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4208        return tracesFile;
4209    }
4210
4211    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4212            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4213        // Use a FileObserver to detect when traces finish writing.
4214        // The order of traces is considered important to maintain for legibility.
4215        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4216            @Override
4217            public synchronized void onEvent(int event, String path) { notify(); }
4218        };
4219
4220        try {
4221            observer.startWatching();
4222
4223            // First collect all of the stacks of the most important pids.
4224            if (firstPids != null) {
4225                try {
4226                    int num = firstPids.size();
4227                    for (int i = 0; i < num; i++) {
4228                        synchronized (observer) {
4229                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4230                            observer.wait(200);  // Wait for write-close, give up after 200msec
4231                        }
4232                    }
4233                } catch (InterruptedException e) {
4234                    Log.wtf(TAG, e);
4235                }
4236            }
4237
4238            // Next collect the stacks of the native pids
4239            if (nativeProcs != null) {
4240                int[] pids = Process.getPidsForCommands(nativeProcs);
4241                if (pids != null) {
4242                    for (int pid : pids) {
4243                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4244                    }
4245                }
4246            }
4247
4248            // Lastly, measure CPU usage.
4249            if (processCpuTracker != null) {
4250                processCpuTracker.init();
4251                System.gc();
4252                processCpuTracker.update();
4253                try {
4254                    synchronized (processCpuTracker) {
4255                        processCpuTracker.wait(500); // measure over 1/2 second.
4256                    }
4257                } catch (InterruptedException e) {
4258                }
4259                processCpuTracker.update();
4260
4261                // We'll take the stack crawls of just the top apps using CPU.
4262                final int N = processCpuTracker.countWorkingStats();
4263                int numProcs = 0;
4264                for (int i=0; i<N && numProcs<5; i++) {
4265                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4266                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4267                        numProcs++;
4268                        try {
4269                            synchronized (observer) {
4270                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4271                                observer.wait(200);  // Wait for write-close, give up after 200msec
4272                            }
4273                        } catch (InterruptedException e) {
4274                            Log.wtf(TAG, e);
4275                        }
4276
4277                    }
4278                }
4279            }
4280        } finally {
4281            observer.stopWatching();
4282        }
4283    }
4284
4285    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4286        if (true || IS_USER_BUILD) {
4287            return;
4288        }
4289        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4290        if (tracesPath == null || tracesPath.length() == 0) {
4291            return;
4292        }
4293
4294        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4295        StrictMode.allowThreadDiskWrites();
4296        try {
4297            final File tracesFile = new File(tracesPath);
4298            final File tracesDir = tracesFile.getParentFile();
4299            final File tracesTmp = new File(tracesDir, "__tmp__");
4300            try {
4301                if (!tracesDir.exists()) {
4302                    tracesFile.mkdirs();
4303                    if (!SELinux.restorecon(tracesDir.getPath())) {
4304                        return;
4305                    }
4306                }
4307                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4308
4309                if (tracesFile.exists()) {
4310                    tracesTmp.delete();
4311                    tracesFile.renameTo(tracesTmp);
4312                }
4313                StringBuilder sb = new StringBuilder();
4314                Time tobj = new Time();
4315                tobj.set(System.currentTimeMillis());
4316                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4317                sb.append(": ");
4318                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4319                sb.append(" since ");
4320                sb.append(msg);
4321                FileOutputStream fos = new FileOutputStream(tracesFile);
4322                fos.write(sb.toString().getBytes());
4323                if (app == null) {
4324                    fos.write("\n*** No application process!".getBytes());
4325                }
4326                fos.close();
4327                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4328            } catch (IOException e) {
4329                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4330                return;
4331            }
4332
4333            if (app != null) {
4334                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4335                firstPids.add(app.pid);
4336                dumpStackTraces(tracesPath, firstPids, null, null, null);
4337            }
4338
4339            File lastTracesFile = null;
4340            File curTracesFile = null;
4341            for (int i=9; i>=0; i--) {
4342                String name = String.format(Locale.US, "slow%02d.txt", i);
4343                curTracesFile = new File(tracesDir, name);
4344                if (curTracesFile.exists()) {
4345                    if (lastTracesFile != null) {
4346                        curTracesFile.renameTo(lastTracesFile);
4347                    } else {
4348                        curTracesFile.delete();
4349                    }
4350                }
4351                lastTracesFile = curTracesFile;
4352            }
4353            tracesFile.renameTo(curTracesFile);
4354            if (tracesTmp.exists()) {
4355                tracesTmp.renameTo(tracesFile);
4356            }
4357        } finally {
4358            StrictMode.setThreadPolicy(oldPolicy);
4359        }
4360    }
4361
4362    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4363            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4364        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4365        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4366
4367        if (mController != null) {
4368            try {
4369                // 0 == continue, -1 = kill process immediately
4370                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4371                if (res < 0 && app.pid != MY_PID) {
4372                    Process.killProcess(app.pid);
4373                    Process.killProcessGroup(app.info.uid, app.pid);
4374                }
4375            } catch (RemoteException e) {
4376                mController = null;
4377                Watchdog.getInstance().setActivityController(null);
4378            }
4379        }
4380
4381        long anrTime = SystemClock.uptimeMillis();
4382        if (MONITOR_CPU_USAGE) {
4383            updateCpuStatsNow();
4384        }
4385
4386        synchronized (this) {
4387            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4388            if (mShuttingDown) {
4389                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4390                return;
4391            } else if (app.notResponding) {
4392                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4393                return;
4394            } else if (app.crashing) {
4395                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4396                return;
4397            }
4398
4399            // In case we come through here for the same app before completing
4400            // this one, mark as anring now so we will bail out.
4401            app.notResponding = true;
4402
4403            // Log the ANR to the event log.
4404            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4405                    app.processName, app.info.flags, annotation);
4406
4407            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4408            firstPids.add(app.pid);
4409
4410            int parentPid = app.pid;
4411            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4412            if (parentPid != app.pid) firstPids.add(parentPid);
4413
4414            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4415
4416            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4417                ProcessRecord r = mLruProcesses.get(i);
4418                if (r != null && r.thread != null) {
4419                    int pid = r.pid;
4420                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4421                        if (r.persistent) {
4422                            firstPids.add(pid);
4423                        } else {
4424                            lastPids.put(pid, Boolean.TRUE);
4425                        }
4426                    }
4427                }
4428            }
4429        }
4430
4431        // Log the ANR to the main log.
4432        StringBuilder info = new StringBuilder();
4433        info.setLength(0);
4434        info.append("ANR in ").append(app.processName);
4435        if (activity != null && activity.shortComponentName != null) {
4436            info.append(" (").append(activity.shortComponentName).append(")");
4437        }
4438        info.append("\n");
4439        info.append("PID: ").append(app.pid).append("\n");
4440        if (annotation != null) {
4441            info.append("Reason: ").append(annotation).append("\n");
4442        }
4443        if (parent != null && parent != activity) {
4444            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4445        }
4446
4447        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4448
4449        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4450                NATIVE_STACKS_OF_INTEREST);
4451
4452        String cpuInfo = null;
4453        if (MONITOR_CPU_USAGE) {
4454            updateCpuStatsNow();
4455            synchronized (mProcessCpuThread) {
4456                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4457            }
4458            info.append(processCpuTracker.printCurrentLoad());
4459            info.append(cpuInfo);
4460        }
4461
4462        info.append(processCpuTracker.printCurrentState(anrTime));
4463
4464        Slog.e(TAG, info.toString());
4465        if (tracesFile == null) {
4466            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4467            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4468        }
4469
4470        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4471                cpuInfo, tracesFile, null);
4472
4473        if (mController != null) {
4474            try {
4475                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4476                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4477                if (res != 0) {
4478                    if (res < 0 && app.pid != MY_PID) {
4479                        Process.killProcess(app.pid);
4480                        Process.killProcessGroup(app.info.uid, app.pid);
4481                    } else {
4482                        synchronized (this) {
4483                            mServices.scheduleServiceTimeoutLocked(app);
4484                        }
4485                    }
4486                    return;
4487                }
4488            } catch (RemoteException e) {
4489                mController = null;
4490                Watchdog.getInstance().setActivityController(null);
4491            }
4492        }
4493
4494        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4495        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4496                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4497
4498        synchronized (this) {
4499            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4500                killUnneededProcessLocked(app, "background ANR");
4501                return;
4502            }
4503
4504            // Set the app's notResponding state, and look up the errorReportReceiver
4505            makeAppNotRespondingLocked(app,
4506                    activity != null ? activity.shortComponentName : null,
4507                    annotation != null ? "ANR " + annotation : "ANR",
4508                    info.toString());
4509
4510            // Bring up the infamous App Not Responding dialog
4511            Message msg = Message.obtain();
4512            HashMap<String, Object> map = new HashMap<String, Object>();
4513            msg.what = SHOW_NOT_RESPONDING_MSG;
4514            msg.obj = map;
4515            msg.arg1 = aboveSystem ? 1 : 0;
4516            map.put("app", app);
4517            if (activity != null) {
4518                map.put("activity", activity);
4519            }
4520
4521            mHandler.sendMessage(msg);
4522        }
4523    }
4524
4525    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4526        if (!mLaunchWarningShown) {
4527            mLaunchWarningShown = true;
4528            mHandler.post(new Runnable() {
4529                @Override
4530                public void run() {
4531                    synchronized (ActivityManagerService.this) {
4532                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4533                        d.show();
4534                        mHandler.postDelayed(new Runnable() {
4535                            @Override
4536                            public void run() {
4537                                synchronized (ActivityManagerService.this) {
4538                                    d.dismiss();
4539                                    mLaunchWarningShown = false;
4540                                }
4541                            }
4542                        }, 4000);
4543                    }
4544                }
4545            });
4546        }
4547    }
4548
4549    @Override
4550    public boolean clearApplicationUserData(final String packageName,
4551            final IPackageDataObserver observer, int userId) {
4552        enforceNotIsolatedCaller("clearApplicationUserData");
4553        int uid = Binder.getCallingUid();
4554        int pid = Binder.getCallingPid();
4555        userId = handleIncomingUser(pid, uid,
4556                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4557        long callingId = Binder.clearCallingIdentity();
4558        try {
4559            IPackageManager pm = AppGlobals.getPackageManager();
4560            int pkgUid = -1;
4561            synchronized(this) {
4562                try {
4563                    pkgUid = pm.getPackageUid(packageName, userId);
4564                } catch (RemoteException e) {
4565                }
4566                if (pkgUid == -1) {
4567                    Slog.w(TAG, "Invalid packageName: " + packageName);
4568                    if (observer != null) {
4569                        try {
4570                            observer.onRemoveCompleted(packageName, false);
4571                        } catch (RemoteException e) {
4572                            Slog.i(TAG, "Observer no longer exists.");
4573                        }
4574                    }
4575                    return false;
4576                }
4577                if (uid == pkgUid || checkComponentPermission(
4578                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4579                        pid, uid, -1, true)
4580                        == PackageManager.PERMISSION_GRANTED) {
4581                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4582                } else {
4583                    throw new SecurityException("PID " + pid + " does not have permission "
4584                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4585                                    + " of package " + packageName);
4586                }
4587            }
4588
4589            try {
4590                // Clear application user data
4591                pm.clearApplicationUserData(packageName, observer, userId);
4592
4593                // Remove all permissions granted from/to this package
4594                removeUriPermissionsForPackageLocked(packageName, userId, true);
4595
4596                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4597                        Uri.fromParts("package", packageName, null));
4598                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4599                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4600                        null, null, 0, null, null, null, false, false, userId);
4601            } catch (RemoteException e) {
4602            }
4603        } finally {
4604            Binder.restoreCallingIdentity(callingId);
4605        }
4606        return true;
4607    }
4608
4609    @Override
4610    public void killBackgroundProcesses(final String packageName, int userId) {
4611        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4612                != PackageManager.PERMISSION_GRANTED &&
4613                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4614                        != PackageManager.PERMISSION_GRANTED) {
4615            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4616                    + Binder.getCallingPid()
4617                    + ", uid=" + Binder.getCallingUid()
4618                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4619            Slog.w(TAG, msg);
4620            throw new SecurityException(msg);
4621        }
4622
4623        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4624                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4625        long callingId = Binder.clearCallingIdentity();
4626        try {
4627            IPackageManager pm = AppGlobals.getPackageManager();
4628            synchronized(this) {
4629                int appId = -1;
4630                try {
4631                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4632                } catch (RemoteException e) {
4633                }
4634                if (appId == -1) {
4635                    Slog.w(TAG, "Invalid packageName: " + packageName);
4636                    return;
4637                }
4638                killPackageProcessesLocked(packageName, appId, userId,
4639                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4640            }
4641        } finally {
4642            Binder.restoreCallingIdentity(callingId);
4643        }
4644    }
4645
4646    @Override
4647    public void killAllBackgroundProcesses() {
4648        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4649                != PackageManager.PERMISSION_GRANTED) {
4650            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4651                    + Binder.getCallingPid()
4652                    + ", uid=" + Binder.getCallingUid()
4653                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4654            Slog.w(TAG, msg);
4655            throw new SecurityException(msg);
4656        }
4657
4658        long callingId = Binder.clearCallingIdentity();
4659        try {
4660            synchronized(this) {
4661                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4662                final int NP = mProcessNames.getMap().size();
4663                for (int ip=0; ip<NP; ip++) {
4664                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4665                    final int NA = apps.size();
4666                    for (int ia=0; ia<NA; ia++) {
4667                        ProcessRecord app = apps.valueAt(ia);
4668                        if (app.persistent) {
4669                            // we don't kill persistent processes
4670                            continue;
4671                        }
4672                        if (app.removed) {
4673                            procs.add(app);
4674                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4675                            app.removed = true;
4676                            procs.add(app);
4677                        }
4678                    }
4679                }
4680
4681                int N = procs.size();
4682                for (int i=0; i<N; i++) {
4683                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4684                }
4685                mAllowLowerMemLevel = true;
4686                updateOomAdjLocked();
4687                doLowMemReportIfNeededLocked(null);
4688            }
4689        } finally {
4690            Binder.restoreCallingIdentity(callingId);
4691        }
4692    }
4693
4694    @Override
4695    public void forceStopPackage(final String packageName, int userId) {
4696        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4697                != PackageManager.PERMISSION_GRANTED) {
4698            String msg = "Permission Denial: forceStopPackage() from pid="
4699                    + Binder.getCallingPid()
4700                    + ", uid=" + Binder.getCallingUid()
4701                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4702            Slog.w(TAG, msg);
4703            throw new SecurityException(msg);
4704        }
4705        final int callingPid = Binder.getCallingPid();
4706        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4707                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4708        long callingId = Binder.clearCallingIdentity();
4709        try {
4710            IPackageManager pm = AppGlobals.getPackageManager();
4711            synchronized(this) {
4712                int[] users = userId == UserHandle.USER_ALL
4713                        ? getUsersLocked() : new int[] { userId };
4714                for (int user : users) {
4715                    int pkgUid = -1;
4716                    try {
4717                        pkgUid = pm.getPackageUid(packageName, user);
4718                    } catch (RemoteException e) {
4719                    }
4720                    if (pkgUid == -1) {
4721                        Slog.w(TAG, "Invalid packageName: " + packageName);
4722                        continue;
4723                    }
4724                    try {
4725                        pm.setPackageStoppedState(packageName, true, user);
4726                    } catch (RemoteException e) {
4727                    } catch (IllegalArgumentException e) {
4728                        Slog.w(TAG, "Failed trying to unstop package "
4729                                + packageName + ": " + e);
4730                    }
4731                    if (isUserRunningLocked(user, false)) {
4732                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4733                    }
4734                }
4735            }
4736        } finally {
4737            Binder.restoreCallingIdentity(callingId);
4738        }
4739    }
4740
4741    @Override
4742    public void addPackageDependency(String packageName) {
4743        synchronized (this) {
4744            int callingPid = Binder.getCallingPid();
4745            if (callingPid == Process.myPid()) {
4746                //  Yeah, um, no.
4747                Slog.w(TAG, "Can't addPackageDependency on system process");
4748                return;
4749            }
4750            ProcessRecord proc;
4751            synchronized (mPidsSelfLocked) {
4752                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4753            }
4754            if (proc != null) {
4755                if (proc.pkgDeps == null) {
4756                    proc.pkgDeps = new ArraySet<String>(1);
4757                }
4758                proc.pkgDeps.add(packageName);
4759            }
4760        }
4761    }
4762
4763    /*
4764     * The pkg name and app id have to be specified.
4765     */
4766    @Override
4767    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4768        if (pkg == null) {
4769            return;
4770        }
4771        // Make sure the uid is valid.
4772        if (appid < 0) {
4773            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4774            return;
4775        }
4776        int callerUid = Binder.getCallingUid();
4777        // Only the system server can kill an application
4778        if (callerUid == Process.SYSTEM_UID) {
4779            // Post an aysnc message to kill the application
4780            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4781            msg.arg1 = appid;
4782            msg.arg2 = 0;
4783            Bundle bundle = new Bundle();
4784            bundle.putString("pkg", pkg);
4785            bundle.putString("reason", reason);
4786            msg.obj = bundle;
4787            mHandler.sendMessage(msg);
4788        } else {
4789            throw new SecurityException(callerUid + " cannot kill pkg: " +
4790                    pkg);
4791        }
4792    }
4793
4794    @Override
4795    public void closeSystemDialogs(String reason) {
4796        enforceNotIsolatedCaller("closeSystemDialogs");
4797
4798        final int pid = Binder.getCallingPid();
4799        final int uid = Binder.getCallingUid();
4800        final long origId = Binder.clearCallingIdentity();
4801        try {
4802            synchronized (this) {
4803                // Only allow this from foreground processes, so that background
4804                // applications can't abuse it to prevent system UI from being shown.
4805                if (uid >= Process.FIRST_APPLICATION_UID) {
4806                    ProcessRecord proc;
4807                    synchronized (mPidsSelfLocked) {
4808                        proc = mPidsSelfLocked.get(pid);
4809                    }
4810                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4811                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4812                                + " from background process " + proc);
4813                        return;
4814                    }
4815                }
4816                closeSystemDialogsLocked(reason);
4817            }
4818        } finally {
4819            Binder.restoreCallingIdentity(origId);
4820        }
4821    }
4822
4823    void closeSystemDialogsLocked(String reason) {
4824        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4825        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4826                | Intent.FLAG_RECEIVER_FOREGROUND);
4827        if (reason != null) {
4828            intent.putExtra("reason", reason);
4829        }
4830        mWindowManager.closeSystemDialogs(reason);
4831
4832        mStackSupervisor.closeSystemDialogsLocked();
4833
4834        broadcastIntentLocked(null, null, intent, null,
4835                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4836                Process.SYSTEM_UID, UserHandle.USER_ALL);
4837    }
4838
4839    @Override
4840    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4841        enforceNotIsolatedCaller("getProcessMemoryInfo");
4842        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4843        for (int i=pids.length-1; i>=0; i--) {
4844            ProcessRecord proc;
4845            int oomAdj;
4846            synchronized (this) {
4847                synchronized (mPidsSelfLocked) {
4848                    proc = mPidsSelfLocked.get(pids[i]);
4849                    oomAdj = proc != null ? proc.setAdj : 0;
4850                }
4851            }
4852            infos[i] = new Debug.MemoryInfo();
4853            Debug.getMemoryInfo(pids[i], infos[i]);
4854            if (proc != null) {
4855                synchronized (this) {
4856                    if (proc.thread != null && proc.setAdj == oomAdj) {
4857                        // Record this for posterity if the process has been stable.
4858                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4859                                infos[i].getTotalUss(), false, proc.pkgList);
4860                    }
4861                }
4862            }
4863        }
4864        return infos;
4865    }
4866
4867    @Override
4868    public long[] getProcessPss(int[] pids) {
4869        enforceNotIsolatedCaller("getProcessPss");
4870        long[] pss = new long[pids.length];
4871        for (int i=pids.length-1; i>=0; i--) {
4872            ProcessRecord proc;
4873            int oomAdj;
4874            synchronized (this) {
4875                synchronized (mPidsSelfLocked) {
4876                    proc = mPidsSelfLocked.get(pids[i]);
4877                    oomAdj = proc != null ? proc.setAdj : 0;
4878                }
4879            }
4880            long[] tmpUss = new long[1];
4881            pss[i] = Debug.getPss(pids[i], tmpUss);
4882            if (proc != null) {
4883                synchronized (this) {
4884                    if (proc.thread != null && proc.setAdj == oomAdj) {
4885                        // Record this for posterity if the process has been stable.
4886                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4887                    }
4888                }
4889            }
4890        }
4891        return pss;
4892    }
4893
4894    @Override
4895    public void killApplicationProcess(String processName, int uid) {
4896        if (processName == null) {
4897            return;
4898        }
4899
4900        int callerUid = Binder.getCallingUid();
4901        // Only the system server can kill an application
4902        if (callerUid == Process.SYSTEM_UID) {
4903            synchronized (this) {
4904                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4905                if (app != null && app.thread != null) {
4906                    try {
4907                        app.thread.scheduleSuicide();
4908                    } catch (RemoteException e) {
4909                        // If the other end already died, then our work here is done.
4910                    }
4911                } else {
4912                    Slog.w(TAG, "Process/uid not found attempting kill of "
4913                            + processName + " / " + uid);
4914                }
4915            }
4916        } else {
4917            throw new SecurityException(callerUid + " cannot kill app process: " +
4918                    processName);
4919        }
4920    }
4921
4922    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4923        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4924                false, true, false, false, UserHandle.getUserId(uid), reason);
4925        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4926                Uri.fromParts("package", packageName, null));
4927        if (!mProcessesReady) {
4928            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4929                    | Intent.FLAG_RECEIVER_FOREGROUND);
4930        }
4931        intent.putExtra(Intent.EXTRA_UID, uid);
4932        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4933        broadcastIntentLocked(null, null, intent,
4934                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4935                false, false,
4936                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4937    }
4938
4939    private void forceStopUserLocked(int userId, String reason) {
4940        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4941        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4942        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4943                | Intent.FLAG_RECEIVER_FOREGROUND);
4944        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4945        broadcastIntentLocked(null, null, intent,
4946                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4947                false, false,
4948                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4949    }
4950
4951    private final boolean killPackageProcessesLocked(String packageName, int appId,
4952            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4953            boolean doit, boolean evenPersistent, String reason) {
4954        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4955
4956        // Remove all processes this package may have touched: all with the
4957        // same UID (except for the system or root user), and all whose name
4958        // matches the package name.
4959        final int NP = mProcessNames.getMap().size();
4960        for (int ip=0; ip<NP; ip++) {
4961            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4962            final int NA = apps.size();
4963            for (int ia=0; ia<NA; ia++) {
4964                ProcessRecord app = apps.valueAt(ia);
4965                if (app.persistent && !evenPersistent) {
4966                    // we don't kill persistent processes
4967                    continue;
4968                }
4969                if (app.removed) {
4970                    if (doit) {
4971                        procs.add(app);
4972                    }
4973                    continue;
4974                }
4975
4976                // Skip process if it doesn't meet our oom adj requirement.
4977                if (app.setAdj < minOomAdj) {
4978                    continue;
4979                }
4980
4981                // If no package is specified, we call all processes under the
4982                // give user id.
4983                if (packageName == null) {
4984                    if (app.userId != userId) {
4985                        continue;
4986                    }
4987                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4988                        continue;
4989                    }
4990                // Package has been specified, we want to hit all processes
4991                // that match it.  We need to qualify this by the processes
4992                // that are running under the specified app and user ID.
4993                } else {
4994                    final boolean isDep = app.pkgDeps != null
4995                            && app.pkgDeps.contains(packageName);
4996                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4997                        continue;
4998                    }
4999                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5000                        continue;
5001                    }
5002                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5003                        continue;
5004                    }
5005                }
5006
5007                // Process has passed all conditions, kill it!
5008                if (!doit) {
5009                    return true;
5010                }
5011                app.removed = true;
5012                procs.add(app);
5013            }
5014        }
5015
5016        int N = procs.size();
5017        for (int i=0; i<N; i++) {
5018            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5019        }
5020        updateOomAdjLocked();
5021        return N > 0;
5022    }
5023
5024    private final boolean forceStopPackageLocked(String name, int appId,
5025            boolean callerWillRestart, boolean purgeCache, boolean doit,
5026            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5027        int i;
5028        int N;
5029
5030        if (userId == UserHandle.USER_ALL && name == null) {
5031            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5032        }
5033
5034        if (appId < 0 && name != null) {
5035            try {
5036                appId = UserHandle.getAppId(
5037                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5038            } catch (RemoteException e) {
5039            }
5040        }
5041
5042        if (doit) {
5043            if (name != null) {
5044                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5045                        + " user=" + userId + ": " + reason);
5046            } else {
5047                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5048            }
5049
5050            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5051            for (int ip=pmap.size()-1; ip>=0; ip--) {
5052                SparseArray<Long> ba = pmap.valueAt(ip);
5053                for (i=ba.size()-1; i>=0; i--) {
5054                    boolean remove = false;
5055                    final int entUid = ba.keyAt(i);
5056                    if (name != null) {
5057                        if (userId == UserHandle.USER_ALL) {
5058                            if (UserHandle.getAppId(entUid) == appId) {
5059                                remove = true;
5060                            }
5061                        } else {
5062                            if (entUid == UserHandle.getUid(userId, appId)) {
5063                                remove = true;
5064                            }
5065                        }
5066                    } else if (UserHandle.getUserId(entUid) == userId) {
5067                        remove = true;
5068                    }
5069                    if (remove) {
5070                        ba.removeAt(i);
5071                    }
5072                }
5073                if (ba.size() == 0) {
5074                    pmap.removeAt(ip);
5075                }
5076            }
5077        }
5078
5079        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5080                -100, callerWillRestart, true, doit, evenPersistent,
5081                name == null ? ("stop user " + userId) : ("stop " + name));
5082
5083        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5084            if (!doit) {
5085                return true;
5086            }
5087            didSomething = true;
5088        }
5089
5090        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5091            if (!doit) {
5092                return true;
5093            }
5094            didSomething = true;
5095        }
5096
5097        if (name == null) {
5098            // Remove all sticky broadcasts from this user.
5099            mStickyBroadcasts.remove(userId);
5100        }
5101
5102        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5103        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5104                userId, providers)) {
5105            if (!doit) {
5106                return true;
5107            }
5108            didSomething = true;
5109        }
5110        N = providers.size();
5111        for (i=0; i<N; i++) {
5112            removeDyingProviderLocked(null, providers.get(i), true);
5113        }
5114
5115        // Remove transient permissions granted from/to this package/user
5116        removeUriPermissionsForPackageLocked(name, userId, false);
5117
5118        if (name == null || uninstalling) {
5119            // Remove pending intents.  For now we only do this when force
5120            // stopping users, because we have some problems when doing this
5121            // for packages -- app widgets are not currently cleaned up for
5122            // such packages, so they can be left with bad pending intents.
5123            if (mIntentSenderRecords.size() > 0) {
5124                Iterator<WeakReference<PendingIntentRecord>> it
5125                        = mIntentSenderRecords.values().iterator();
5126                while (it.hasNext()) {
5127                    WeakReference<PendingIntentRecord> wpir = it.next();
5128                    if (wpir == null) {
5129                        it.remove();
5130                        continue;
5131                    }
5132                    PendingIntentRecord pir = wpir.get();
5133                    if (pir == null) {
5134                        it.remove();
5135                        continue;
5136                    }
5137                    if (name == null) {
5138                        // Stopping user, remove all objects for the user.
5139                        if (pir.key.userId != userId) {
5140                            // Not the same user, skip it.
5141                            continue;
5142                        }
5143                    } else {
5144                        if (UserHandle.getAppId(pir.uid) != appId) {
5145                            // Different app id, skip it.
5146                            continue;
5147                        }
5148                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5149                            // Different user, skip it.
5150                            continue;
5151                        }
5152                        if (!pir.key.packageName.equals(name)) {
5153                            // Different package, skip it.
5154                            continue;
5155                        }
5156                    }
5157                    if (!doit) {
5158                        return true;
5159                    }
5160                    didSomething = true;
5161                    it.remove();
5162                    pir.canceled = true;
5163                    if (pir.key.activity != null) {
5164                        pir.key.activity.pendingResults.remove(pir.ref);
5165                    }
5166                }
5167            }
5168        }
5169
5170        if (doit) {
5171            if (purgeCache && name != null) {
5172                AttributeCache ac = AttributeCache.instance();
5173                if (ac != null) {
5174                    ac.removePackage(name);
5175                }
5176            }
5177            if (mBooted) {
5178                mStackSupervisor.resumeTopActivitiesLocked();
5179                mStackSupervisor.scheduleIdleLocked();
5180            }
5181        }
5182
5183        return didSomething;
5184    }
5185
5186    private final boolean removeProcessLocked(ProcessRecord app,
5187            boolean callerWillRestart, boolean allowRestart, String reason) {
5188        final String name = app.processName;
5189        final int uid = app.uid;
5190        if (DEBUG_PROCESSES) Slog.d(
5191            TAG, "Force removing proc " + app.toShortString() + " (" + name
5192            + "/" + uid + ")");
5193
5194        mProcessNames.remove(name, uid);
5195        mIsolatedProcesses.remove(app.uid);
5196        if (mHeavyWeightProcess == app) {
5197            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5198                    mHeavyWeightProcess.userId, 0));
5199            mHeavyWeightProcess = null;
5200        }
5201        boolean needRestart = false;
5202        if (app.pid > 0 && app.pid != MY_PID) {
5203            int pid = app.pid;
5204            synchronized (mPidsSelfLocked) {
5205                mPidsSelfLocked.remove(pid);
5206                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5207            }
5208            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5209            if (app.isolated) {
5210                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5211            }
5212            killUnneededProcessLocked(app, reason);
5213            Process.killProcessGroup(app.info.uid, app.pid);
5214            handleAppDiedLocked(app, true, allowRestart);
5215            removeLruProcessLocked(app);
5216
5217            if (app.persistent && !app.isolated) {
5218                if (!callerWillRestart) {
5219                    addAppLocked(app.info, false, null /* ABI override */);
5220                } else {
5221                    needRestart = true;
5222                }
5223            }
5224        } else {
5225            mRemovedProcesses.add(app);
5226        }
5227
5228        return needRestart;
5229    }
5230
5231    private final void processStartTimedOutLocked(ProcessRecord app) {
5232        final int pid = app.pid;
5233        boolean gone = false;
5234        synchronized (mPidsSelfLocked) {
5235            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5236            if (knownApp != null && knownApp.thread == null) {
5237                mPidsSelfLocked.remove(pid);
5238                gone = true;
5239            }
5240        }
5241
5242        if (gone) {
5243            Slog.w(TAG, "Process " + app + " failed to attach");
5244            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5245                    pid, app.uid, app.processName);
5246            mProcessNames.remove(app.processName, app.uid);
5247            mIsolatedProcesses.remove(app.uid);
5248            if (mHeavyWeightProcess == app) {
5249                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5250                        mHeavyWeightProcess.userId, 0));
5251                mHeavyWeightProcess = null;
5252            }
5253            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5254            if (app.isolated) {
5255                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5256            }
5257            // Take care of any launching providers waiting for this process.
5258            checkAppInLaunchingProvidersLocked(app, true);
5259            // Take care of any services that are waiting for the process.
5260            mServices.processStartTimedOutLocked(app);
5261            killUnneededProcessLocked(app, "start timeout");
5262            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5263                Slog.w(TAG, "Unattached app died before backup, skipping");
5264                try {
5265                    IBackupManager bm = IBackupManager.Stub.asInterface(
5266                            ServiceManager.getService(Context.BACKUP_SERVICE));
5267                    bm.agentDisconnected(app.info.packageName);
5268                } catch (RemoteException e) {
5269                    // Can't happen; the backup manager is local
5270                }
5271            }
5272            if (isPendingBroadcastProcessLocked(pid)) {
5273                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5274                skipPendingBroadcastLocked(pid);
5275            }
5276        } else {
5277            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5278        }
5279    }
5280
5281    private final boolean attachApplicationLocked(IApplicationThread thread,
5282            int pid) {
5283
5284        // Find the application record that is being attached...  either via
5285        // the pid if we are running in multiple processes, or just pull the
5286        // next app record if we are emulating process with anonymous threads.
5287        ProcessRecord app;
5288        if (pid != MY_PID && pid >= 0) {
5289            synchronized (mPidsSelfLocked) {
5290                app = mPidsSelfLocked.get(pid);
5291            }
5292        } else {
5293            app = null;
5294        }
5295
5296        if (app == null) {
5297            Slog.w(TAG, "No pending application record for pid " + pid
5298                    + " (IApplicationThread " + thread + "); dropping process");
5299            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5300            if (pid > 0 && pid != MY_PID) {
5301                Process.killProcessQuiet(pid);
5302                //TODO: Process.killProcessGroup(app.info.uid, pid);
5303            } else {
5304                try {
5305                    thread.scheduleExit();
5306                } catch (Exception e) {
5307                    // Ignore exceptions.
5308                }
5309            }
5310            return false;
5311        }
5312
5313        // If this application record is still attached to a previous
5314        // process, clean it up now.
5315        if (app.thread != null) {
5316            handleAppDiedLocked(app, true, true);
5317        }
5318
5319        // Tell the process all about itself.
5320
5321        if (localLOGV) Slog.v(
5322                TAG, "Binding process pid " + pid + " to record " + app);
5323
5324        final String processName = app.processName;
5325        try {
5326            AppDeathRecipient adr = new AppDeathRecipient(
5327                    app, pid, thread);
5328            thread.asBinder().linkToDeath(adr, 0);
5329            app.deathRecipient = adr;
5330        } catch (RemoteException e) {
5331            app.resetPackageList(mProcessStats);
5332            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5333            return false;
5334        }
5335
5336        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5337
5338        app.makeActive(thread, mProcessStats);
5339        app.curAdj = app.setAdj = -100;
5340        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5341        app.forcingToForeground = null;
5342        updateProcessForegroundLocked(app, false, false);
5343        app.hasShownUi = false;
5344        app.debugging = false;
5345        app.cached = false;
5346
5347        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5348
5349        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5350        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5351
5352        if (!normalMode) {
5353            Slog.i(TAG, "Launching preboot mode app: " + app);
5354        }
5355
5356        if (localLOGV) Slog.v(
5357            TAG, "New app record " + app
5358            + " thread=" + thread.asBinder() + " pid=" + pid);
5359        try {
5360            int testMode = IApplicationThread.DEBUG_OFF;
5361            if (mDebugApp != null && mDebugApp.equals(processName)) {
5362                testMode = mWaitForDebugger
5363                    ? IApplicationThread.DEBUG_WAIT
5364                    : IApplicationThread.DEBUG_ON;
5365                app.debugging = true;
5366                if (mDebugTransient) {
5367                    mDebugApp = mOrigDebugApp;
5368                    mWaitForDebugger = mOrigWaitForDebugger;
5369                }
5370            }
5371            String profileFile = app.instrumentationProfileFile;
5372            ParcelFileDescriptor profileFd = null;
5373            boolean profileAutoStop = false;
5374            if (mProfileApp != null && mProfileApp.equals(processName)) {
5375                mProfileProc = app;
5376                profileFile = mProfileFile;
5377                profileFd = mProfileFd;
5378                profileAutoStop = mAutoStopProfiler;
5379            }
5380            boolean enableOpenGlTrace = false;
5381            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5382                enableOpenGlTrace = true;
5383                mOpenGlTraceApp = null;
5384            }
5385
5386            // If the app is being launched for restore or full backup, set it up specially
5387            boolean isRestrictedBackupMode = false;
5388            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5389                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5390                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5391                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5392            }
5393
5394            ensurePackageDexOpt(app.instrumentationInfo != null
5395                    ? app.instrumentationInfo.packageName
5396                    : app.info.packageName);
5397            if (app.instrumentationClass != null) {
5398                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5399            }
5400            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5401                    + processName + " with config " + mConfiguration);
5402            ApplicationInfo appInfo = app.instrumentationInfo != null
5403                    ? app.instrumentationInfo : app.info;
5404            app.compat = compatibilityInfoForPackageLocked(appInfo);
5405            if (profileFd != null) {
5406                profileFd = profileFd.dup();
5407            }
5408            thread.bindApplication(processName, appInfo, providers,
5409                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5410                    app.instrumentationArguments, app.instrumentationWatcher,
5411                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5412                    isRestrictedBackupMode || !normalMode, app.persistent,
5413                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5414                    mCoreSettingsObserver.getCoreSettingsLocked());
5415            updateLruProcessLocked(app, false, null);
5416            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5417        } catch (Exception e) {
5418            // todo: Yikes!  What should we do?  For now we will try to
5419            // start another process, but that could easily get us in
5420            // an infinite loop of restarting processes...
5421            Slog.w(TAG, "Exception thrown during bind!", e);
5422
5423            app.resetPackageList(mProcessStats);
5424            app.unlinkDeathRecipient();
5425            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5426            return false;
5427        }
5428
5429        // Remove this record from the list of starting applications.
5430        mPersistentStartingProcesses.remove(app);
5431        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5432                "Attach application locked removing on hold: " + app);
5433        mProcessesOnHold.remove(app);
5434
5435        boolean badApp = false;
5436        boolean didSomething = false;
5437
5438        // See if the top visible activity is waiting to run in this process...
5439        if (normalMode) {
5440            try {
5441                if (mStackSupervisor.attachApplicationLocked(app)) {
5442                    didSomething = true;
5443                }
5444            } catch (Exception e) {
5445                badApp = true;
5446            }
5447        }
5448
5449        // Find any services that should be running in this process...
5450        if (!badApp) {
5451            try {
5452                didSomething |= mServices.attachApplicationLocked(app, processName);
5453            } catch (Exception e) {
5454                badApp = true;
5455            }
5456        }
5457
5458        // Check if a next-broadcast receiver is in this process...
5459        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5460            try {
5461                didSomething |= sendPendingBroadcastsLocked(app);
5462            } catch (Exception e) {
5463                // If the app died trying to launch the receiver we declare it 'bad'
5464                badApp = true;
5465            }
5466        }
5467
5468        // Check whether the next backup agent is in this process...
5469        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5470            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5471            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5472            try {
5473                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5474                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5475                        mBackupTarget.backupMode);
5476            } catch (Exception e) {
5477                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5478                e.printStackTrace();
5479            }
5480        }
5481
5482        if (badApp) {
5483            // todo: Also need to kill application to deal with all
5484            // kinds of exceptions.
5485            handleAppDiedLocked(app, false, true);
5486            return false;
5487        }
5488
5489        if (!didSomething) {
5490            updateOomAdjLocked();
5491        }
5492
5493        return true;
5494    }
5495
5496    @Override
5497    public final void attachApplication(IApplicationThread thread) {
5498        synchronized (this) {
5499            int callingPid = Binder.getCallingPid();
5500            final long origId = Binder.clearCallingIdentity();
5501            attachApplicationLocked(thread, callingPid);
5502            Binder.restoreCallingIdentity(origId);
5503        }
5504    }
5505
5506    @Override
5507    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5508        final long origId = Binder.clearCallingIdentity();
5509        synchronized (this) {
5510            ActivityStack stack = ActivityRecord.getStackLocked(token);
5511            if (stack != null) {
5512                ActivityRecord r =
5513                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5514                if (stopProfiling) {
5515                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5516                        try {
5517                            mProfileFd.close();
5518                        } catch (IOException e) {
5519                        }
5520                        clearProfilerLocked();
5521                    }
5522                }
5523            }
5524        }
5525        Binder.restoreCallingIdentity(origId);
5526    }
5527
5528    void enableScreenAfterBoot() {
5529        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5530                SystemClock.uptimeMillis());
5531        mWindowManager.enableScreenAfterBoot();
5532
5533        synchronized (this) {
5534            updateEventDispatchingLocked();
5535        }
5536    }
5537
5538    @Override
5539    public void showBootMessage(final CharSequence msg, final boolean always) {
5540        enforceNotIsolatedCaller("showBootMessage");
5541        mWindowManager.showBootMessage(msg, always);
5542    }
5543
5544    @Override
5545    public void dismissKeyguardOnNextActivity() {
5546        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5547        final long token = Binder.clearCallingIdentity();
5548        try {
5549            synchronized (this) {
5550                if (DEBUG_LOCKSCREEN) logLockScreen("");
5551                if (mLockScreenShown) {
5552                    mLockScreenShown = false;
5553                    comeOutOfSleepIfNeededLocked();
5554                }
5555                mStackSupervisor.setDismissKeyguard(true);
5556            }
5557        } finally {
5558            Binder.restoreCallingIdentity(token);
5559        }
5560    }
5561
5562    final void finishBooting() {
5563        // Register receivers to handle package update events
5564        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5565
5566        synchronized (this) {
5567            // Ensure that any processes we had put on hold are now started
5568            // up.
5569            final int NP = mProcessesOnHold.size();
5570            if (NP > 0) {
5571                ArrayList<ProcessRecord> procs =
5572                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5573                for (int ip=0; ip<NP; ip++) {
5574                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5575                            + procs.get(ip));
5576                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5577                }
5578            }
5579
5580            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5581                // Start looking for apps that are abusing wake locks.
5582                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5583                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5584                // Tell anyone interested that we are done booting!
5585                SystemProperties.set("sys.boot_completed", "1");
5586                SystemProperties.set("dev.bootcomplete", "1");
5587                for (int i=0; i<mStartedUsers.size(); i++) {
5588                    UserStartedState uss = mStartedUsers.valueAt(i);
5589                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5590                        uss.mState = UserStartedState.STATE_RUNNING;
5591                        final int userId = mStartedUsers.keyAt(i);
5592                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5593                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5594                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5595                        broadcastIntentLocked(null, null, intent, null,
5596                                new IIntentReceiver.Stub() {
5597                                    @Override
5598                                    public void performReceive(Intent intent, int resultCode,
5599                                            String data, Bundle extras, boolean ordered,
5600                                            boolean sticky, int sendingUser) {
5601                                        synchronized (ActivityManagerService.this) {
5602                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5603                                                    true, false);
5604                                        }
5605                                    }
5606                                },
5607                                0, null, null,
5608                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5609                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5610                                userId);
5611                    }
5612                }
5613                scheduleStartProfilesLocked();
5614            }
5615        }
5616    }
5617
5618    final void ensureBootCompleted() {
5619        boolean booting;
5620        boolean enableScreen;
5621        synchronized (this) {
5622            booting = mBooting;
5623            mBooting = false;
5624            enableScreen = !mBooted;
5625            mBooted = true;
5626        }
5627
5628        if (booting) {
5629            finishBooting();
5630        }
5631
5632        if (enableScreen) {
5633            enableScreenAfterBoot();
5634        }
5635    }
5636
5637    @Override
5638    public final void activityResumed(IBinder token) {
5639        final long origId = Binder.clearCallingIdentity();
5640        synchronized(this) {
5641            ActivityStack stack = ActivityRecord.getStackLocked(token);
5642            if (stack != null) {
5643                ActivityRecord.activityResumedLocked(token);
5644            }
5645        }
5646        Binder.restoreCallingIdentity(origId);
5647    }
5648
5649    @Override
5650    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5651        final long origId = Binder.clearCallingIdentity();
5652        synchronized(this) {
5653            ActivityStack stack = ActivityRecord.getStackLocked(token);
5654            if (stack != null) {
5655                stack.activityPausedLocked(token, false, persistentState);
5656            }
5657        }
5658        Binder.restoreCallingIdentity(origId);
5659    }
5660
5661    @Override
5662    public final void activityStopped(IBinder token, Bundle icicle,
5663            PersistableBundle persistentState, CharSequence description) {
5664        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5665
5666        // Refuse possible leaked file descriptors
5667        if (icicle != null && icicle.hasFileDescriptors()) {
5668            throw new IllegalArgumentException("File descriptors passed in Bundle");
5669        }
5670
5671        final long origId = Binder.clearCallingIdentity();
5672
5673        synchronized (this) {
5674            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5675            if (r != null) {
5676                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5677            }
5678        }
5679
5680        trimApplications();
5681
5682        Binder.restoreCallingIdentity(origId);
5683    }
5684
5685    @Override
5686    public final void activityDestroyed(IBinder token) {
5687        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5688        synchronized (this) {
5689            ActivityStack stack = ActivityRecord.getStackLocked(token);
5690            if (stack != null) {
5691                stack.activityDestroyedLocked(token);
5692            }
5693        }
5694    }
5695
5696    @Override
5697    public final void mediaResourcesReleased(IBinder token) {
5698        final long origId = Binder.clearCallingIdentity();
5699        try {
5700            synchronized (this) {
5701                ActivityStack stack = ActivityRecord.getStackLocked(token);
5702                if (stack != null) {
5703                    stack.mediaResourcesReleased(token);
5704                }
5705            }
5706        } finally {
5707            Binder.restoreCallingIdentity(origId);
5708        }
5709    }
5710
5711    @Override
5712    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5713        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5714    }
5715
5716    @Override
5717    public final void notifyEnterAnimationComplete(IBinder token) {
5718        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5719    }
5720
5721    @Override
5722    public String getCallingPackage(IBinder token) {
5723        synchronized (this) {
5724            ActivityRecord r = getCallingRecordLocked(token);
5725            return r != null ? r.info.packageName : null;
5726        }
5727    }
5728
5729    @Override
5730    public ComponentName getCallingActivity(IBinder token) {
5731        synchronized (this) {
5732            ActivityRecord r = getCallingRecordLocked(token);
5733            return r != null ? r.intent.getComponent() : null;
5734        }
5735    }
5736
5737    private ActivityRecord getCallingRecordLocked(IBinder token) {
5738        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5739        if (r == null) {
5740            return null;
5741        }
5742        return r.resultTo;
5743    }
5744
5745    @Override
5746    public ComponentName getActivityClassForToken(IBinder token) {
5747        synchronized(this) {
5748            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5749            if (r == null) {
5750                return null;
5751            }
5752            return r.intent.getComponent();
5753        }
5754    }
5755
5756    @Override
5757    public String getPackageForToken(IBinder token) {
5758        synchronized(this) {
5759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5760            if (r == null) {
5761                return null;
5762            }
5763            return r.packageName;
5764        }
5765    }
5766
5767    @Override
5768    public IIntentSender getIntentSender(int type,
5769            String packageName, IBinder token, String resultWho,
5770            int requestCode, Intent[] intents, String[] resolvedTypes,
5771            int flags, Bundle options, int userId) {
5772        enforceNotIsolatedCaller("getIntentSender");
5773        // Refuse possible leaked file descriptors
5774        if (intents != null) {
5775            if (intents.length < 1) {
5776                throw new IllegalArgumentException("Intents array length must be >= 1");
5777            }
5778            for (int i=0; i<intents.length; i++) {
5779                Intent intent = intents[i];
5780                if (intent != null) {
5781                    if (intent.hasFileDescriptors()) {
5782                        throw new IllegalArgumentException("File descriptors passed in Intent");
5783                    }
5784                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5785                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5786                        throw new IllegalArgumentException(
5787                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5788                    }
5789                    intents[i] = new Intent(intent);
5790                }
5791            }
5792            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5793                throw new IllegalArgumentException(
5794                        "Intent array length does not match resolvedTypes length");
5795            }
5796        }
5797        if (options != null) {
5798            if (options.hasFileDescriptors()) {
5799                throw new IllegalArgumentException("File descriptors passed in options");
5800            }
5801        }
5802
5803        synchronized(this) {
5804            int callingUid = Binder.getCallingUid();
5805            int origUserId = userId;
5806            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5807                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5808                    ALLOW_NON_FULL, "getIntentSender", null);
5809            if (origUserId == UserHandle.USER_CURRENT) {
5810                // We don't want to evaluate this until the pending intent is
5811                // actually executed.  However, we do want to always do the
5812                // security checking for it above.
5813                userId = UserHandle.USER_CURRENT;
5814            }
5815            try {
5816                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5817                    int uid = AppGlobals.getPackageManager()
5818                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5819                    if (!UserHandle.isSameApp(callingUid, uid)) {
5820                        String msg = "Permission Denial: getIntentSender() from pid="
5821                            + Binder.getCallingPid()
5822                            + ", uid=" + Binder.getCallingUid()
5823                            + ", (need uid=" + uid + ")"
5824                            + " is not allowed to send as package " + packageName;
5825                        Slog.w(TAG, msg);
5826                        throw new SecurityException(msg);
5827                    }
5828                }
5829
5830                return getIntentSenderLocked(type, packageName, callingUid, userId,
5831                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5832
5833            } catch (RemoteException e) {
5834                throw new SecurityException(e);
5835            }
5836        }
5837    }
5838
5839    IIntentSender getIntentSenderLocked(int type, String packageName,
5840            int callingUid, int userId, IBinder token, String resultWho,
5841            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5842            Bundle options) {
5843        if (DEBUG_MU)
5844            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5845        ActivityRecord activity = null;
5846        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5847            activity = ActivityRecord.isInStackLocked(token);
5848            if (activity == null) {
5849                return null;
5850            }
5851            if (activity.finishing) {
5852                return null;
5853            }
5854        }
5855
5856        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5857        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5858        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5859        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5860                |PendingIntent.FLAG_UPDATE_CURRENT);
5861
5862        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5863                type, packageName, activity, resultWho,
5864                requestCode, intents, resolvedTypes, flags, options, userId);
5865        WeakReference<PendingIntentRecord> ref;
5866        ref = mIntentSenderRecords.get(key);
5867        PendingIntentRecord rec = ref != null ? ref.get() : null;
5868        if (rec != null) {
5869            if (!cancelCurrent) {
5870                if (updateCurrent) {
5871                    if (rec.key.requestIntent != null) {
5872                        rec.key.requestIntent.replaceExtras(intents != null ?
5873                                intents[intents.length - 1] : null);
5874                    }
5875                    if (intents != null) {
5876                        intents[intents.length-1] = rec.key.requestIntent;
5877                        rec.key.allIntents = intents;
5878                        rec.key.allResolvedTypes = resolvedTypes;
5879                    } else {
5880                        rec.key.allIntents = null;
5881                        rec.key.allResolvedTypes = null;
5882                    }
5883                }
5884                return rec;
5885            }
5886            rec.canceled = true;
5887            mIntentSenderRecords.remove(key);
5888        }
5889        if (noCreate) {
5890            return rec;
5891        }
5892        rec = new PendingIntentRecord(this, key, callingUid);
5893        mIntentSenderRecords.put(key, rec.ref);
5894        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5895            if (activity.pendingResults == null) {
5896                activity.pendingResults
5897                        = new HashSet<WeakReference<PendingIntentRecord>>();
5898            }
5899            activity.pendingResults.add(rec.ref);
5900        }
5901        return rec;
5902    }
5903
5904    @Override
5905    public void cancelIntentSender(IIntentSender sender) {
5906        if (!(sender instanceof PendingIntentRecord)) {
5907            return;
5908        }
5909        synchronized(this) {
5910            PendingIntentRecord rec = (PendingIntentRecord)sender;
5911            try {
5912                int uid = AppGlobals.getPackageManager()
5913                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5914                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5915                    String msg = "Permission Denial: cancelIntentSender() from pid="
5916                        + Binder.getCallingPid()
5917                        + ", uid=" + Binder.getCallingUid()
5918                        + " is not allowed to cancel packges "
5919                        + rec.key.packageName;
5920                    Slog.w(TAG, msg);
5921                    throw new SecurityException(msg);
5922                }
5923            } catch (RemoteException e) {
5924                throw new SecurityException(e);
5925            }
5926            cancelIntentSenderLocked(rec, true);
5927        }
5928    }
5929
5930    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5931        rec.canceled = true;
5932        mIntentSenderRecords.remove(rec.key);
5933        if (cleanActivity && rec.key.activity != null) {
5934            rec.key.activity.pendingResults.remove(rec.ref);
5935        }
5936    }
5937
5938    @Override
5939    public String getPackageForIntentSender(IIntentSender pendingResult) {
5940        if (!(pendingResult instanceof PendingIntentRecord)) {
5941            return null;
5942        }
5943        try {
5944            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5945            return res.key.packageName;
5946        } catch (ClassCastException e) {
5947        }
5948        return null;
5949    }
5950
5951    @Override
5952    public int getUidForIntentSender(IIntentSender sender) {
5953        if (sender instanceof PendingIntentRecord) {
5954            try {
5955                PendingIntentRecord res = (PendingIntentRecord)sender;
5956                return res.uid;
5957            } catch (ClassCastException e) {
5958            }
5959        }
5960        return -1;
5961    }
5962
5963    @Override
5964    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5965        if (!(pendingResult instanceof PendingIntentRecord)) {
5966            return false;
5967        }
5968        try {
5969            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5970            if (res.key.allIntents == null) {
5971                return false;
5972            }
5973            for (int i=0; i<res.key.allIntents.length; i++) {
5974                Intent intent = res.key.allIntents[i];
5975                if (intent.getPackage() != null && intent.getComponent() != null) {
5976                    return false;
5977                }
5978            }
5979            return true;
5980        } catch (ClassCastException e) {
5981        }
5982        return false;
5983    }
5984
5985    @Override
5986    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5987        if (!(pendingResult instanceof PendingIntentRecord)) {
5988            return false;
5989        }
5990        try {
5991            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5992            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5993                return true;
5994            }
5995            return false;
5996        } catch (ClassCastException e) {
5997        }
5998        return false;
5999    }
6000
6001    @Override
6002    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6003        if (!(pendingResult instanceof PendingIntentRecord)) {
6004            return null;
6005        }
6006        try {
6007            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6008            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6009        } catch (ClassCastException e) {
6010        }
6011        return null;
6012    }
6013
6014    @Override
6015    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6016        if (!(pendingResult instanceof PendingIntentRecord)) {
6017            return null;
6018        }
6019        try {
6020            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6021            Intent intent = res.key.requestIntent;
6022            if (intent != null) {
6023                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6024                        || res.lastTagPrefix.equals(prefix))) {
6025                    return res.lastTag;
6026                }
6027                res.lastTagPrefix = prefix;
6028                StringBuilder sb = new StringBuilder(128);
6029                if (prefix != null) {
6030                    sb.append(prefix);
6031                }
6032                if (intent.getAction() != null) {
6033                    sb.append(intent.getAction());
6034                } else if (intent.getComponent() != null) {
6035                    intent.getComponent().appendShortString(sb);
6036                } else {
6037                    sb.append("?");
6038                }
6039                return res.lastTag = sb.toString();
6040            }
6041        } catch (ClassCastException e) {
6042        }
6043        return null;
6044    }
6045
6046    @Override
6047    public void setProcessLimit(int max) {
6048        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6049                "setProcessLimit()");
6050        synchronized (this) {
6051            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6052            mProcessLimitOverride = max;
6053        }
6054        trimApplications();
6055    }
6056
6057    @Override
6058    public int getProcessLimit() {
6059        synchronized (this) {
6060            return mProcessLimitOverride;
6061        }
6062    }
6063
6064    void foregroundTokenDied(ForegroundToken token) {
6065        synchronized (ActivityManagerService.this) {
6066            synchronized (mPidsSelfLocked) {
6067                ForegroundToken cur
6068                    = mForegroundProcesses.get(token.pid);
6069                if (cur != token) {
6070                    return;
6071                }
6072                mForegroundProcesses.remove(token.pid);
6073                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6074                if (pr == null) {
6075                    return;
6076                }
6077                pr.forcingToForeground = null;
6078                updateProcessForegroundLocked(pr, false, false);
6079            }
6080            updateOomAdjLocked();
6081        }
6082    }
6083
6084    @Override
6085    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6086        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6087                "setProcessForeground()");
6088        synchronized(this) {
6089            boolean changed = false;
6090
6091            synchronized (mPidsSelfLocked) {
6092                ProcessRecord pr = mPidsSelfLocked.get(pid);
6093                if (pr == null && isForeground) {
6094                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6095                    return;
6096                }
6097                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6098                if (oldToken != null) {
6099                    oldToken.token.unlinkToDeath(oldToken, 0);
6100                    mForegroundProcesses.remove(pid);
6101                    if (pr != null) {
6102                        pr.forcingToForeground = null;
6103                    }
6104                    changed = true;
6105                }
6106                if (isForeground && token != null) {
6107                    ForegroundToken newToken = new ForegroundToken() {
6108                        @Override
6109                        public void binderDied() {
6110                            foregroundTokenDied(this);
6111                        }
6112                    };
6113                    newToken.pid = pid;
6114                    newToken.token = token;
6115                    try {
6116                        token.linkToDeath(newToken, 0);
6117                        mForegroundProcesses.put(pid, newToken);
6118                        pr.forcingToForeground = token;
6119                        changed = true;
6120                    } catch (RemoteException e) {
6121                        // If the process died while doing this, we will later
6122                        // do the cleanup with the process death link.
6123                    }
6124                }
6125            }
6126
6127            if (changed) {
6128                updateOomAdjLocked();
6129            }
6130        }
6131    }
6132
6133    // =========================================================
6134    // PERMISSIONS
6135    // =========================================================
6136
6137    static class PermissionController extends IPermissionController.Stub {
6138        ActivityManagerService mActivityManagerService;
6139        PermissionController(ActivityManagerService activityManagerService) {
6140            mActivityManagerService = activityManagerService;
6141        }
6142
6143        @Override
6144        public boolean checkPermission(String permission, int pid, int uid) {
6145            return mActivityManagerService.checkPermission(permission, pid,
6146                    uid) == PackageManager.PERMISSION_GRANTED;
6147        }
6148    }
6149
6150    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6151        @Override
6152        public int checkComponentPermission(String permission, int pid, int uid,
6153                int owningUid, boolean exported) {
6154            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6155                    owningUid, exported);
6156        }
6157
6158        @Override
6159        public Object getAMSLock() {
6160            return ActivityManagerService.this;
6161        }
6162    }
6163
6164    /**
6165     * This can be called with or without the global lock held.
6166     */
6167    int checkComponentPermission(String permission, int pid, int uid,
6168            int owningUid, boolean exported) {
6169        // We might be performing an operation on behalf of an indirect binder
6170        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6171        // client identity accordingly before proceeding.
6172        Identity tlsIdentity = sCallerIdentity.get();
6173        if (tlsIdentity != null) {
6174            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6175                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6176            uid = tlsIdentity.uid;
6177            pid = tlsIdentity.pid;
6178        }
6179
6180        if (pid == MY_PID) {
6181            return PackageManager.PERMISSION_GRANTED;
6182        }
6183
6184        return ActivityManager.checkComponentPermission(permission, uid,
6185                owningUid, exported);
6186    }
6187
6188    /**
6189     * As the only public entry point for permissions checking, this method
6190     * can enforce the semantic that requesting a check on a null global
6191     * permission is automatically denied.  (Internally a null permission
6192     * string is used when calling {@link #checkComponentPermission} in cases
6193     * when only uid-based security is needed.)
6194     *
6195     * This can be called with or without the global lock held.
6196     */
6197    @Override
6198    public int checkPermission(String permission, int pid, int uid) {
6199        if (permission == null) {
6200            return PackageManager.PERMISSION_DENIED;
6201        }
6202        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6203    }
6204
6205    /**
6206     * Binder IPC calls go through the public entry point.
6207     * This can be called with or without the global lock held.
6208     */
6209    int checkCallingPermission(String permission) {
6210        return checkPermission(permission,
6211                Binder.getCallingPid(),
6212                UserHandle.getAppId(Binder.getCallingUid()));
6213    }
6214
6215    /**
6216     * This can be called with or without the global lock held.
6217     */
6218    void enforceCallingPermission(String permission, String func) {
6219        if (checkCallingPermission(permission)
6220                == PackageManager.PERMISSION_GRANTED) {
6221            return;
6222        }
6223
6224        String msg = "Permission Denial: " + func + " from pid="
6225                + Binder.getCallingPid()
6226                + ", uid=" + Binder.getCallingUid()
6227                + " requires " + permission;
6228        Slog.w(TAG, msg);
6229        throw new SecurityException(msg);
6230    }
6231
6232    /**
6233     * Determine if UID is holding permissions required to access {@link Uri} in
6234     * the given {@link ProviderInfo}. Final permission checking is always done
6235     * in {@link ContentProvider}.
6236     */
6237    private final boolean checkHoldingPermissionsLocked(
6238            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6239        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6240                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6241        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6242            return false;
6243        }
6244        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6245    }
6246
6247    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6248            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6249        if (pi.applicationInfo.uid == uid) {
6250            return true;
6251        } else if (!pi.exported) {
6252            return false;
6253        }
6254
6255        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6256        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6257        try {
6258            // check if target holds top-level <provider> permissions
6259            if (!readMet && pi.readPermission != null && considerUidPermissions
6260                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6261                readMet = true;
6262            }
6263            if (!writeMet && pi.writePermission != null && considerUidPermissions
6264                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6265                writeMet = true;
6266            }
6267
6268            // track if unprotected read/write is allowed; any denied
6269            // <path-permission> below removes this ability
6270            boolean allowDefaultRead = pi.readPermission == null;
6271            boolean allowDefaultWrite = pi.writePermission == null;
6272
6273            // check if target holds any <path-permission> that match uri
6274            final PathPermission[] pps = pi.pathPermissions;
6275            if (pps != null) {
6276                final String path = grantUri.uri.getPath();
6277                int i = pps.length;
6278                while (i > 0 && (!readMet || !writeMet)) {
6279                    i--;
6280                    PathPermission pp = pps[i];
6281                    if (pp.match(path)) {
6282                        if (!readMet) {
6283                            final String pprperm = pp.getReadPermission();
6284                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6285                                    + pprperm + " for " + pp.getPath()
6286                                    + ": match=" + pp.match(path)
6287                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6288                            if (pprperm != null) {
6289                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6290                                        == PERMISSION_GRANTED) {
6291                                    readMet = true;
6292                                } else {
6293                                    allowDefaultRead = false;
6294                                }
6295                            }
6296                        }
6297                        if (!writeMet) {
6298                            final String ppwperm = pp.getWritePermission();
6299                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6300                                    + ppwperm + " for " + pp.getPath()
6301                                    + ": match=" + pp.match(path)
6302                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6303                            if (ppwperm != null) {
6304                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6305                                        == PERMISSION_GRANTED) {
6306                                    writeMet = true;
6307                                } else {
6308                                    allowDefaultWrite = false;
6309                                }
6310                            }
6311                        }
6312                    }
6313                }
6314            }
6315
6316            // grant unprotected <provider> read/write, if not blocked by
6317            // <path-permission> above
6318            if (allowDefaultRead) readMet = true;
6319            if (allowDefaultWrite) writeMet = true;
6320
6321        } catch (RemoteException e) {
6322            return false;
6323        }
6324
6325        return readMet && writeMet;
6326    }
6327
6328    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6329        ProviderInfo pi = null;
6330        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6331        if (cpr != null) {
6332            pi = cpr.info;
6333        } else {
6334            try {
6335                pi = AppGlobals.getPackageManager().resolveContentProvider(
6336                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6337            } catch (RemoteException ex) {
6338            }
6339        }
6340        return pi;
6341    }
6342
6343    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6344        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6345        if (targetUris != null) {
6346            return targetUris.get(grantUri);
6347        }
6348        return null;
6349    }
6350
6351    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6352            String targetPkg, int targetUid, GrantUri grantUri) {
6353        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6354        if (targetUris == null) {
6355            targetUris = Maps.newArrayMap();
6356            mGrantedUriPermissions.put(targetUid, targetUris);
6357        }
6358
6359        UriPermission perm = targetUris.get(grantUri);
6360        if (perm == null) {
6361            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6362            targetUris.put(grantUri, perm);
6363        }
6364
6365        return perm;
6366    }
6367
6368    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6369            final int modeFlags) {
6370        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6371        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6372                : UriPermission.STRENGTH_OWNED;
6373
6374        // Root gets to do everything.
6375        if (uid == 0) {
6376            return true;
6377        }
6378
6379        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6380        if (perms == null) return false;
6381
6382        // First look for exact match
6383        final UriPermission exactPerm = perms.get(grantUri);
6384        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6385            return true;
6386        }
6387
6388        // No exact match, look for prefixes
6389        final int N = perms.size();
6390        for (int i = 0; i < N; i++) {
6391            final UriPermission perm = perms.valueAt(i);
6392            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6393                    && perm.getStrength(modeFlags) >= minStrength) {
6394                return true;
6395            }
6396        }
6397
6398        return false;
6399    }
6400
6401    @Override
6402    public int checkUriPermission(Uri uri, int pid, int uid,
6403            final int modeFlags, int userId) {
6404        enforceNotIsolatedCaller("checkUriPermission");
6405
6406        // Another redirected-binder-call permissions check as in
6407        // {@link checkComponentPermission}.
6408        Identity tlsIdentity = sCallerIdentity.get();
6409        if (tlsIdentity != null) {
6410            uid = tlsIdentity.uid;
6411            pid = tlsIdentity.pid;
6412        }
6413
6414        // Our own process gets to do everything.
6415        if (pid == MY_PID) {
6416            return PackageManager.PERMISSION_GRANTED;
6417        }
6418        synchronized (this) {
6419            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6420                    ? PackageManager.PERMISSION_GRANTED
6421                    : PackageManager.PERMISSION_DENIED;
6422        }
6423    }
6424
6425    /**
6426     * Check if the targetPkg can be granted permission to access uri by
6427     * the callingUid using the given modeFlags.  Throws a security exception
6428     * if callingUid is not allowed to do this.  Returns the uid of the target
6429     * if the URI permission grant should be performed; returns -1 if it is not
6430     * needed (for example targetPkg already has permission to access the URI).
6431     * If you already know the uid of the target, you can supply it in
6432     * lastTargetUid else set that to -1.
6433     */
6434    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6435            final int modeFlags, int lastTargetUid) {
6436        if (!Intent.isAccessUriMode(modeFlags)) {
6437            return -1;
6438        }
6439
6440        if (targetPkg != null) {
6441            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6442                    "Checking grant " + targetPkg + " permission to " + grantUri);
6443        }
6444
6445        final IPackageManager pm = AppGlobals.getPackageManager();
6446
6447        // If this is not a content: uri, we can't do anything with it.
6448        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6449            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6450                    "Can't grant URI permission for non-content URI: " + grantUri);
6451            return -1;
6452        }
6453
6454        final String authority = grantUri.uri.getAuthority();
6455        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6456        if (pi == null) {
6457            Slog.w(TAG, "No content provider found for permission check: " +
6458                    grantUri.uri.toSafeString());
6459            return -1;
6460        }
6461
6462        int targetUid = lastTargetUid;
6463        if (targetUid < 0 && targetPkg != null) {
6464            try {
6465                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6466                if (targetUid < 0) {
6467                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6468                            "Can't grant URI permission no uid for: " + targetPkg);
6469                    return -1;
6470                }
6471            } catch (RemoteException ex) {
6472                return -1;
6473            }
6474        }
6475
6476        if (targetUid >= 0) {
6477            // First...  does the target actually need this permission?
6478            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6479                // No need to grant the target this permission.
6480                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6481                        "Target " + targetPkg + " already has full permission to " + grantUri);
6482                return -1;
6483            }
6484        } else {
6485            // First...  there is no target package, so can anyone access it?
6486            boolean allowed = pi.exported;
6487            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6488                if (pi.readPermission != null) {
6489                    allowed = false;
6490                }
6491            }
6492            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6493                if (pi.writePermission != null) {
6494                    allowed = false;
6495                }
6496            }
6497            if (allowed) {
6498                return -1;
6499            }
6500        }
6501
6502        /* There is a special cross user grant if:
6503         * - The target is on another user.
6504         * - Apps on the current user can access the uri without any uid permissions.
6505         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6506         * grant uri permissions.
6507         */
6508        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6509                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6510                modeFlags, false /*without considering the uid permissions*/);
6511
6512        // Second...  is the provider allowing granting of URI permissions?
6513        if (!specialCrossUserGrant) {
6514            if (!pi.grantUriPermissions) {
6515                throw new SecurityException("Provider " + pi.packageName
6516                        + "/" + pi.name
6517                        + " does not allow granting of Uri permissions (uri "
6518                        + grantUri + ")");
6519            }
6520            if (pi.uriPermissionPatterns != null) {
6521                final int N = pi.uriPermissionPatterns.length;
6522                boolean allowed = false;
6523                for (int i=0; i<N; i++) {
6524                    if (pi.uriPermissionPatterns[i] != null
6525                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6526                        allowed = true;
6527                        break;
6528                    }
6529                }
6530                if (!allowed) {
6531                    throw new SecurityException("Provider " + pi.packageName
6532                            + "/" + pi.name
6533                            + " does not allow granting of permission to path of Uri "
6534                            + grantUri);
6535                }
6536            }
6537        }
6538
6539        // Third...  does the caller itself have permission to access
6540        // this uri?
6541        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6542            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6543                // Require they hold a strong enough Uri permission
6544                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6545                    throw new SecurityException("Uid " + callingUid
6546                            + " does not have permission to uri " + grantUri);
6547                }
6548            }
6549        }
6550        return targetUid;
6551    }
6552
6553    @Override
6554    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6555            final int modeFlags, int userId) {
6556        enforceNotIsolatedCaller("checkGrantUriPermission");
6557        synchronized(this) {
6558            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6559                    new GrantUri(userId, uri, false), modeFlags, -1);
6560        }
6561    }
6562
6563    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6564            final int modeFlags, UriPermissionOwner owner) {
6565        if (!Intent.isAccessUriMode(modeFlags)) {
6566            return;
6567        }
6568
6569        // So here we are: the caller has the assumed permission
6570        // to the uri, and the target doesn't.  Let's now give this to
6571        // the target.
6572
6573        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6574                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6575
6576        final String authority = grantUri.uri.getAuthority();
6577        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6578        if (pi == null) {
6579            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6580            return;
6581        }
6582
6583        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6584            grantUri.prefix = true;
6585        }
6586        final UriPermission perm = findOrCreateUriPermissionLocked(
6587                pi.packageName, targetPkg, targetUid, grantUri);
6588        perm.grantModes(modeFlags, owner);
6589    }
6590
6591    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6592            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6593        if (targetPkg == null) {
6594            throw new NullPointerException("targetPkg");
6595        }
6596        int targetUid;
6597        final IPackageManager pm = AppGlobals.getPackageManager();
6598        try {
6599            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6600        } catch (RemoteException ex) {
6601            return;
6602        }
6603
6604        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6605                targetUid);
6606        if (targetUid < 0) {
6607            return;
6608        }
6609
6610        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6611                owner);
6612    }
6613
6614    static class NeededUriGrants extends ArrayList<GrantUri> {
6615        final String targetPkg;
6616        final int targetUid;
6617        final int flags;
6618
6619        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6620            this.targetPkg = targetPkg;
6621            this.targetUid = targetUid;
6622            this.flags = flags;
6623        }
6624    }
6625
6626    /**
6627     * Like checkGrantUriPermissionLocked, but takes an Intent.
6628     */
6629    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6630            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6631        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6632                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6633                + " clip=" + (intent != null ? intent.getClipData() : null)
6634                + " from " + intent + "; flags=0x"
6635                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6636
6637        if (targetPkg == null) {
6638            throw new NullPointerException("targetPkg");
6639        }
6640
6641        if (intent == null) {
6642            return null;
6643        }
6644        Uri data = intent.getData();
6645        ClipData clip = intent.getClipData();
6646        if (data == null && clip == null) {
6647            return null;
6648        }
6649        // Default userId for uris in the intent (if they don't specify it themselves)
6650        int contentUserHint = intent.getContentUserHint();
6651        if (contentUserHint == UserHandle.USER_CURRENT) {
6652            contentUserHint = UserHandle.getUserId(callingUid);
6653        }
6654        final IPackageManager pm = AppGlobals.getPackageManager();
6655        int targetUid;
6656        if (needed != null) {
6657            targetUid = needed.targetUid;
6658        } else {
6659            try {
6660                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6661            } catch (RemoteException ex) {
6662                return null;
6663            }
6664            if (targetUid < 0) {
6665                if (DEBUG_URI_PERMISSION) {
6666                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6667                            + " on user " + targetUserId);
6668                }
6669                return null;
6670            }
6671        }
6672        if (data != null) {
6673            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6674            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6675                    targetUid);
6676            if (targetUid > 0) {
6677                if (needed == null) {
6678                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6679                }
6680                needed.add(grantUri);
6681            }
6682        }
6683        if (clip != null) {
6684            for (int i=0; i<clip.getItemCount(); i++) {
6685                Uri uri = clip.getItemAt(i).getUri();
6686                if (uri != null) {
6687                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6688                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6689                            targetUid);
6690                    if (targetUid > 0) {
6691                        if (needed == null) {
6692                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6693                        }
6694                        needed.add(grantUri);
6695                    }
6696                } else {
6697                    Intent clipIntent = clip.getItemAt(i).getIntent();
6698                    if (clipIntent != null) {
6699                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6700                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6701                        if (newNeeded != null) {
6702                            needed = newNeeded;
6703                        }
6704                    }
6705                }
6706            }
6707        }
6708
6709        return needed;
6710    }
6711
6712    /**
6713     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6714     */
6715    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6716            UriPermissionOwner owner) {
6717        if (needed != null) {
6718            for (int i=0; i<needed.size(); i++) {
6719                GrantUri grantUri = needed.get(i);
6720                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6721                        grantUri, needed.flags, owner);
6722            }
6723        }
6724    }
6725
6726    void grantUriPermissionFromIntentLocked(int callingUid,
6727            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6728        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6729                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6730        if (needed == null) {
6731            return;
6732        }
6733
6734        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6735    }
6736
6737    @Override
6738    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6739            final int modeFlags, int userId) {
6740        enforceNotIsolatedCaller("grantUriPermission");
6741        GrantUri grantUri = new GrantUri(userId, uri, false);
6742        synchronized(this) {
6743            final ProcessRecord r = getRecordForAppLocked(caller);
6744            if (r == null) {
6745                throw new SecurityException("Unable to find app for caller "
6746                        + caller
6747                        + " when granting permission to uri " + grantUri);
6748            }
6749            if (targetPkg == null) {
6750                throw new IllegalArgumentException("null target");
6751            }
6752            if (grantUri == null) {
6753                throw new IllegalArgumentException("null uri");
6754            }
6755
6756            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6757                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6758                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6759                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6760
6761            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6762                    UserHandle.getUserId(r.uid));
6763        }
6764    }
6765
6766    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6767        if (perm.modeFlags == 0) {
6768            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6769                    perm.targetUid);
6770            if (perms != null) {
6771                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6772                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6773
6774                perms.remove(perm.uri);
6775                if (perms.isEmpty()) {
6776                    mGrantedUriPermissions.remove(perm.targetUid);
6777                }
6778            }
6779        }
6780    }
6781
6782    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6783        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6784
6785        final IPackageManager pm = AppGlobals.getPackageManager();
6786        final String authority = grantUri.uri.getAuthority();
6787        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6788        if (pi == null) {
6789            Slog.w(TAG, "No content provider found for permission revoke: "
6790                    + grantUri.toSafeString());
6791            return;
6792        }
6793
6794        // Does the caller have this permission on the URI?
6795        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6796            // Right now, if you are not the original owner of the permission,
6797            // you are not allowed to revoke it.
6798            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6799                throw new SecurityException("Uid " + callingUid
6800                        + " does not have permission to uri " + grantUri);
6801            //}
6802        }
6803
6804        boolean persistChanged = false;
6805
6806        // Go through all of the permissions and remove any that match.
6807        int N = mGrantedUriPermissions.size();
6808        for (int i = 0; i < N; i++) {
6809            final int targetUid = mGrantedUriPermissions.keyAt(i);
6810            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6811
6812            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6813                final UriPermission perm = it.next();
6814                if (perm.uri.sourceUserId == grantUri.sourceUserId
6815                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6816                    if (DEBUG_URI_PERMISSION)
6817                        Slog.v(TAG,
6818                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6819                    persistChanged |= perm.revokeModes(
6820                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6821                    if (perm.modeFlags == 0) {
6822                        it.remove();
6823                    }
6824                }
6825            }
6826
6827            if (perms.isEmpty()) {
6828                mGrantedUriPermissions.remove(targetUid);
6829                N--;
6830                i--;
6831            }
6832        }
6833
6834        if (persistChanged) {
6835            schedulePersistUriGrants();
6836        }
6837    }
6838
6839    @Override
6840    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6841            int userId) {
6842        enforceNotIsolatedCaller("revokeUriPermission");
6843        synchronized(this) {
6844            final ProcessRecord r = getRecordForAppLocked(caller);
6845            if (r == null) {
6846                throw new SecurityException("Unable to find app for caller "
6847                        + caller
6848                        + " when revoking permission to uri " + uri);
6849            }
6850            if (uri == null) {
6851                Slog.w(TAG, "revokeUriPermission: null uri");
6852                return;
6853            }
6854
6855            if (!Intent.isAccessUriMode(modeFlags)) {
6856                return;
6857            }
6858
6859            final IPackageManager pm = AppGlobals.getPackageManager();
6860            final String authority = uri.getAuthority();
6861            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6862            if (pi == null) {
6863                Slog.w(TAG, "No content provider found for permission revoke: "
6864                        + uri.toSafeString());
6865                return;
6866            }
6867
6868            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6869        }
6870    }
6871
6872    /**
6873     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6874     * given package.
6875     *
6876     * @param packageName Package name to match, or {@code null} to apply to all
6877     *            packages.
6878     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6879     *            to all users.
6880     * @param persistable If persistable grants should be removed.
6881     */
6882    private void removeUriPermissionsForPackageLocked(
6883            String packageName, int userHandle, boolean persistable) {
6884        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6885            throw new IllegalArgumentException("Must narrow by either package or user");
6886        }
6887
6888        boolean persistChanged = false;
6889
6890        int N = mGrantedUriPermissions.size();
6891        for (int i = 0; i < N; i++) {
6892            final int targetUid = mGrantedUriPermissions.keyAt(i);
6893            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6894
6895            // Only inspect grants matching user
6896            if (userHandle == UserHandle.USER_ALL
6897                    || userHandle == UserHandle.getUserId(targetUid)) {
6898                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6899                    final UriPermission perm = it.next();
6900
6901                    // Only inspect grants matching package
6902                    if (packageName == null || perm.sourcePkg.equals(packageName)
6903                            || perm.targetPkg.equals(packageName)) {
6904                        persistChanged |= perm.revokeModes(
6905                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6906
6907                        // Only remove when no modes remain; any persisted grants
6908                        // will keep this alive.
6909                        if (perm.modeFlags == 0) {
6910                            it.remove();
6911                        }
6912                    }
6913                }
6914
6915                if (perms.isEmpty()) {
6916                    mGrantedUriPermissions.remove(targetUid);
6917                    N--;
6918                    i--;
6919                }
6920            }
6921        }
6922
6923        if (persistChanged) {
6924            schedulePersistUriGrants();
6925        }
6926    }
6927
6928    @Override
6929    public IBinder newUriPermissionOwner(String name) {
6930        enforceNotIsolatedCaller("newUriPermissionOwner");
6931        synchronized(this) {
6932            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6933            return owner.getExternalTokenLocked();
6934        }
6935    }
6936
6937    @Override
6938    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6939            final int modeFlags, int sourceUserId, int targetUserId) {
6940        synchronized(this) {
6941            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6942            if (owner == null) {
6943                throw new IllegalArgumentException("Unknown owner: " + token);
6944            }
6945            if (fromUid != Binder.getCallingUid()) {
6946                if (Binder.getCallingUid() != Process.myUid()) {
6947                    // Only system code can grant URI permissions on behalf
6948                    // of other users.
6949                    throw new SecurityException("nice try");
6950                }
6951            }
6952            if (targetPkg == null) {
6953                throw new IllegalArgumentException("null target");
6954            }
6955            if (uri == null) {
6956                throw new IllegalArgumentException("null uri");
6957            }
6958
6959            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6960                    modeFlags, owner, targetUserId);
6961        }
6962    }
6963
6964    @Override
6965    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6966        synchronized(this) {
6967            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6968            if (owner == null) {
6969                throw new IllegalArgumentException("Unknown owner: " + token);
6970            }
6971
6972            if (uri == null) {
6973                owner.removeUriPermissionsLocked(mode);
6974            } else {
6975                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6976            }
6977        }
6978    }
6979
6980    private void schedulePersistUriGrants() {
6981        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6982            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6983                    10 * DateUtils.SECOND_IN_MILLIS);
6984        }
6985    }
6986
6987    private void writeGrantedUriPermissions() {
6988        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6989
6990        // Snapshot permissions so we can persist without lock
6991        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6992        synchronized (this) {
6993            final int size = mGrantedUriPermissions.size();
6994            for (int i = 0; i < size; i++) {
6995                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6996                for (UriPermission perm : perms.values()) {
6997                    if (perm.persistedModeFlags != 0) {
6998                        persist.add(perm.snapshot());
6999                    }
7000                }
7001            }
7002        }
7003
7004        FileOutputStream fos = null;
7005        try {
7006            fos = mGrantFile.startWrite();
7007
7008            XmlSerializer out = new FastXmlSerializer();
7009            out.setOutput(fos, "utf-8");
7010            out.startDocument(null, true);
7011            out.startTag(null, TAG_URI_GRANTS);
7012            for (UriPermission.Snapshot perm : persist) {
7013                out.startTag(null, TAG_URI_GRANT);
7014                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7015                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7016                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7017                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7018                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7019                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7020                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7021                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7022                out.endTag(null, TAG_URI_GRANT);
7023            }
7024            out.endTag(null, TAG_URI_GRANTS);
7025            out.endDocument();
7026
7027            mGrantFile.finishWrite(fos);
7028        } catch (IOException e) {
7029            if (fos != null) {
7030                mGrantFile.failWrite(fos);
7031            }
7032        }
7033    }
7034
7035    private void readGrantedUriPermissionsLocked() {
7036        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7037
7038        final long now = System.currentTimeMillis();
7039
7040        FileInputStream fis = null;
7041        try {
7042            fis = mGrantFile.openRead();
7043            final XmlPullParser in = Xml.newPullParser();
7044            in.setInput(fis, null);
7045
7046            int type;
7047            while ((type = in.next()) != END_DOCUMENT) {
7048                final String tag = in.getName();
7049                if (type == START_TAG) {
7050                    if (TAG_URI_GRANT.equals(tag)) {
7051                        final int sourceUserId;
7052                        final int targetUserId;
7053                        final int userHandle = readIntAttribute(in,
7054                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7055                        if (userHandle != UserHandle.USER_NULL) {
7056                            // For backwards compatibility.
7057                            sourceUserId = userHandle;
7058                            targetUserId = userHandle;
7059                        } else {
7060                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7061                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7062                        }
7063                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7064                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7065                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7066                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7067                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7068                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7069
7070                        // Sanity check that provider still belongs to source package
7071                        final ProviderInfo pi = getProviderInfoLocked(
7072                                uri.getAuthority(), sourceUserId);
7073                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7074                            int targetUid = -1;
7075                            try {
7076                                targetUid = AppGlobals.getPackageManager()
7077                                        .getPackageUid(targetPkg, targetUserId);
7078                            } catch (RemoteException e) {
7079                            }
7080                            if (targetUid != -1) {
7081                                final UriPermission perm = findOrCreateUriPermissionLocked(
7082                                        sourcePkg, targetPkg, targetUid,
7083                                        new GrantUri(sourceUserId, uri, prefix));
7084                                perm.initPersistedModes(modeFlags, createdTime);
7085                            }
7086                        } else {
7087                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7088                                    + " but instead found " + pi);
7089                        }
7090                    }
7091                }
7092            }
7093        } catch (FileNotFoundException e) {
7094            // Missing grants is okay
7095        } catch (IOException e) {
7096            Log.wtf(TAG, "Failed reading Uri grants", e);
7097        } catch (XmlPullParserException e) {
7098            Log.wtf(TAG, "Failed reading Uri grants", e);
7099        } finally {
7100            IoUtils.closeQuietly(fis);
7101        }
7102    }
7103
7104    @Override
7105    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7106        enforceNotIsolatedCaller("takePersistableUriPermission");
7107
7108        Preconditions.checkFlagsArgument(modeFlags,
7109                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7110
7111        synchronized (this) {
7112            final int callingUid = Binder.getCallingUid();
7113            boolean persistChanged = false;
7114            GrantUri grantUri = new GrantUri(userId, uri, false);
7115
7116            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7117                    new GrantUri(userId, uri, false));
7118            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7119                    new GrantUri(userId, uri, true));
7120
7121            final boolean exactValid = (exactPerm != null)
7122                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7123            final boolean prefixValid = (prefixPerm != null)
7124                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7125
7126            if (!(exactValid || prefixValid)) {
7127                throw new SecurityException("No persistable permission grants found for UID "
7128                        + callingUid + " and Uri " + grantUri.toSafeString());
7129            }
7130
7131            if (exactValid) {
7132                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7133            }
7134            if (prefixValid) {
7135                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7136            }
7137
7138            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7139
7140            if (persistChanged) {
7141                schedulePersistUriGrants();
7142            }
7143        }
7144    }
7145
7146    @Override
7147    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7148        enforceNotIsolatedCaller("releasePersistableUriPermission");
7149
7150        Preconditions.checkFlagsArgument(modeFlags,
7151                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7152
7153        synchronized (this) {
7154            final int callingUid = Binder.getCallingUid();
7155            boolean persistChanged = false;
7156
7157            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7158                    new GrantUri(userId, uri, false));
7159            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7160                    new GrantUri(userId, uri, true));
7161            if (exactPerm == null && prefixPerm == null) {
7162                throw new SecurityException("No permission grants found for UID " + callingUid
7163                        + " and Uri " + uri.toSafeString());
7164            }
7165
7166            if (exactPerm != null) {
7167                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7168                removeUriPermissionIfNeededLocked(exactPerm);
7169            }
7170            if (prefixPerm != null) {
7171                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7172                removeUriPermissionIfNeededLocked(prefixPerm);
7173            }
7174
7175            if (persistChanged) {
7176                schedulePersistUriGrants();
7177            }
7178        }
7179    }
7180
7181    /**
7182     * Prune any older {@link UriPermission} for the given UID until outstanding
7183     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7184     *
7185     * @return if any mutations occured that require persisting.
7186     */
7187    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7188        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7189        if (perms == null) return false;
7190        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7191
7192        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7193        for (UriPermission perm : perms.values()) {
7194            if (perm.persistedModeFlags != 0) {
7195                persisted.add(perm);
7196            }
7197        }
7198
7199        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7200        if (trimCount <= 0) return false;
7201
7202        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7203        for (int i = 0; i < trimCount; i++) {
7204            final UriPermission perm = persisted.get(i);
7205
7206            if (DEBUG_URI_PERMISSION) {
7207                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7208            }
7209
7210            perm.releasePersistableModes(~0);
7211            removeUriPermissionIfNeededLocked(perm);
7212        }
7213
7214        return true;
7215    }
7216
7217    @Override
7218    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7219            String packageName, boolean incoming) {
7220        enforceNotIsolatedCaller("getPersistedUriPermissions");
7221        Preconditions.checkNotNull(packageName, "packageName");
7222
7223        final int callingUid = Binder.getCallingUid();
7224        final IPackageManager pm = AppGlobals.getPackageManager();
7225        try {
7226            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7227            if (packageUid != callingUid) {
7228                throw new SecurityException(
7229                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7230            }
7231        } catch (RemoteException e) {
7232            throw new SecurityException("Failed to verify package name ownership");
7233        }
7234
7235        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7236        synchronized (this) {
7237            if (incoming) {
7238                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7239                        callingUid);
7240                if (perms == null) {
7241                    Slog.w(TAG, "No permission grants found for " + packageName);
7242                } else {
7243                    for (UriPermission perm : perms.values()) {
7244                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7245                            result.add(perm.buildPersistedPublicApiObject());
7246                        }
7247                    }
7248                }
7249            } else {
7250                final int size = mGrantedUriPermissions.size();
7251                for (int i = 0; i < size; i++) {
7252                    final ArrayMap<GrantUri, UriPermission> perms =
7253                            mGrantedUriPermissions.valueAt(i);
7254                    for (UriPermission perm : perms.values()) {
7255                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7256                            result.add(perm.buildPersistedPublicApiObject());
7257                        }
7258                    }
7259                }
7260            }
7261        }
7262        return new ParceledListSlice<android.content.UriPermission>(result);
7263    }
7264
7265    @Override
7266    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7267        synchronized (this) {
7268            ProcessRecord app =
7269                who != null ? getRecordForAppLocked(who) : null;
7270            if (app == null) return;
7271
7272            Message msg = Message.obtain();
7273            msg.what = WAIT_FOR_DEBUGGER_MSG;
7274            msg.obj = app;
7275            msg.arg1 = waiting ? 1 : 0;
7276            mHandler.sendMessage(msg);
7277        }
7278    }
7279
7280    @Override
7281    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7282        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7283        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7284        outInfo.availMem = Process.getFreeMemory();
7285        outInfo.totalMem = Process.getTotalMemory();
7286        outInfo.threshold = homeAppMem;
7287        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7288        outInfo.hiddenAppThreshold = cachedAppMem;
7289        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7290                ProcessList.SERVICE_ADJ);
7291        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7292                ProcessList.VISIBLE_APP_ADJ);
7293        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7294                ProcessList.FOREGROUND_APP_ADJ);
7295    }
7296
7297    // =========================================================
7298    // TASK MANAGEMENT
7299    // =========================================================
7300
7301    @Override
7302    public List<IAppTask> getAppTasks() {
7303        final PackageManager pm = mContext.getPackageManager();
7304        int callingUid = Binder.getCallingUid();
7305        long ident = Binder.clearCallingIdentity();
7306
7307        // Compose the list of packages for this id to test against
7308        HashSet<String> packages = new HashSet<String>();
7309        String[] uidPackages = pm.getPackagesForUid(callingUid);
7310        for (int i = 0; i < uidPackages.length; i++) {
7311            packages.add(uidPackages[i]);
7312        }
7313
7314        synchronized(this) {
7315            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7316            try {
7317                if (localLOGV) Slog.v(TAG, "getAppTasks");
7318
7319                final int N = mRecentTasks.size();
7320                for (int i = 0; i < N; i++) {
7321                    TaskRecord tr = mRecentTasks.get(i);
7322                    // Skip tasks that are not created by the caller
7323                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7324                        ActivityManager.RecentTaskInfo taskInfo =
7325                                createRecentTaskInfoFromTaskRecord(tr);
7326                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7327                        list.add(taskImpl);
7328                    }
7329                }
7330            } finally {
7331                Binder.restoreCallingIdentity(ident);
7332            }
7333            return list;
7334        }
7335    }
7336
7337    @Override
7338    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7339        final int callingUid = Binder.getCallingUid();
7340        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7341
7342        synchronized(this) {
7343            if (localLOGV) Slog.v(
7344                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7345
7346            final boolean allowed = checkCallingPermission(
7347                    android.Manifest.permission.GET_TASKS)
7348                    == PackageManager.PERMISSION_GRANTED;
7349            if (!allowed) {
7350                Slog.w(TAG, "getTasks: caller " + callingUid
7351                        + " does not hold GET_TASKS; limiting output");
7352            }
7353
7354            // TODO: Improve with MRU list from all ActivityStacks.
7355            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7356        }
7357
7358        return list;
7359    }
7360
7361    TaskRecord getMostRecentTask() {
7362        return mRecentTasks.get(0);
7363    }
7364
7365    /**
7366     * Creates a new RecentTaskInfo from a TaskRecord.
7367     */
7368    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7369        // Update the task description to reflect any changes in the task stack
7370        tr.updateTaskDescription();
7371
7372        // Compose the recent task info
7373        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7374        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7375        rti.persistentId = tr.taskId;
7376        rti.baseIntent = new Intent(tr.getBaseIntent());
7377        rti.origActivity = tr.origActivity;
7378        rti.description = tr.lastDescription;
7379        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7380        rti.userId = tr.userId;
7381        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7382        rti.firstActiveTime = tr.firstActiveTime;
7383        rti.lastActiveTime = tr.lastActiveTime;
7384        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7385        return rti;
7386    }
7387
7388    @Override
7389    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7390        final int callingUid = Binder.getCallingUid();
7391        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7392                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7393
7394        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7395        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7396        synchronized (this) {
7397            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7398                    == PackageManager.PERMISSION_GRANTED;
7399            if (!allowed) {
7400                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7401                        + " does not hold GET_TASKS; limiting output");
7402            }
7403            final boolean detailed = checkCallingPermission(
7404                    android.Manifest.permission.GET_DETAILED_TASKS)
7405                    == PackageManager.PERMISSION_GRANTED;
7406
7407            IPackageManager pm = AppGlobals.getPackageManager();
7408
7409            final int N = mRecentTasks.size();
7410            ArrayList<ActivityManager.RecentTaskInfo> res
7411                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7412                            maxNum < N ? maxNum : N);
7413
7414            final Set<Integer> includedUsers;
7415            if (includeProfiles) {
7416                includedUsers = getProfileIdsLocked(userId);
7417            } else {
7418                includedUsers = new HashSet<Integer>();
7419            }
7420            includedUsers.add(Integer.valueOf(userId));
7421
7422            // Regroup affiliated tasks together.
7423            for (int i = 0; i < N; ) {
7424                TaskRecord task = mRecentTasks.remove(i);
7425                if (mTmpRecents.contains(task)) {
7426                    continue;
7427                }
7428                int affiliatedTaskId = task.mAffiliatedTaskId;
7429                while (true) {
7430                    TaskRecord next = task.mNextAffiliate;
7431                    if (next == null) {
7432                        break;
7433                    }
7434                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7435                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7436                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7437                        task.setNextAffiliate(null);
7438                        if (next.mPrevAffiliate == task) {
7439                            next.setPrevAffiliate(null);
7440                        }
7441                        break;
7442                    }
7443                    if (next.mPrevAffiliate != task) {
7444                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7445                                next.mPrevAffiliate + " task=" + task);
7446                        next.setPrevAffiliate(null);
7447                        break;
7448                    }
7449                    if (!mRecentTasks.contains(next)) {
7450                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7451                        task.setNextAffiliate(null);
7452                        if (next.mPrevAffiliate == task) {
7453                            next.setPrevAffiliate(null);
7454                        }
7455                        break;
7456                    }
7457                    task = next;
7458                }
7459                // task is now the end of the list
7460                do {
7461                    mRecentTasks.remove(task);
7462                    mRecentTasks.add(i++, task);
7463                    mTmpRecents.add(task);
7464                } while ((task = task.mPrevAffiliate) != null);
7465            }
7466            mTmpRecents.clear();
7467            // mRecentTasks is now in sorted, affiliated order.
7468
7469            for (int i=0; i<N && maxNum > 0; i++) {
7470                TaskRecord tr = mRecentTasks.get(i);
7471                // Only add calling user or related users recent tasks
7472                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7473
7474                // Return the entry if desired by the caller.  We always return
7475                // the first entry, because callers always expect this to be the
7476                // foreground app.  We may filter others if the caller has
7477                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7478                // we should exclude the entry.
7479
7480                if (i == 0
7481                        || withExcluded
7482                        || (tr.intent == null)
7483                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7484                                == 0)) {
7485                    if (!allowed) {
7486                        // If the caller doesn't have the GET_TASKS permission, then only
7487                        // allow them to see a small subset of tasks -- their own and home.
7488                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7489                            continue;
7490                        }
7491                    }
7492                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7493                        // Don't include auto remove tasks that are finished or finishing.
7494                        continue;
7495                    }
7496
7497                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7498                    if (!detailed) {
7499                        rti.baseIntent.replaceExtras((Bundle)null);
7500                    }
7501
7502                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7503                        // Check whether this activity is currently available.
7504                        try {
7505                            if (rti.origActivity != null) {
7506                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7507                                        == null) {
7508                                    continue;
7509                                }
7510                            } else if (rti.baseIntent != null) {
7511                                if (pm.queryIntentActivities(rti.baseIntent,
7512                                        null, 0, userId) == null) {
7513                                    continue;
7514                                }
7515                            }
7516                        } catch (RemoteException e) {
7517                            // Will never happen.
7518                        }
7519                    }
7520
7521                    res.add(rti);
7522                    maxNum--;
7523                }
7524            }
7525            return res;
7526        }
7527    }
7528
7529    private TaskRecord recentTaskForIdLocked(int id) {
7530        final int N = mRecentTasks.size();
7531            for (int i=0; i<N; i++) {
7532                TaskRecord tr = mRecentTasks.get(i);
7533                if (tr.taskId == id) {
7534                    return tr;
7535                }
7536            }
7537            return null;
7538    }
7539
7540    @Override
7541    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7542        synchronized (this) {
7543            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7544                    "getTaskThumbnail()");
7545            TaskRecord tr = recentTaskForIdLocked(id);
7546            if (tr != null) {
7547                return tr.getTaskThumbnailLocked();
7548            }
7549        }
7550        return null;
7551    }
7552
7553    @Override
7554    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7555        synchronized (this) {
7556            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7557            if (r != null) {
7558                r.taskDescription = td;
7559                r.task.updateTaskDescription();
7560            }
7561        }
7562    }
7563
7564    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7565        if (!pr.killedByAm) {
7566            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7567            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7568                    pr.processName, pr.setAdj, reason);
7569            pr.killedByAm = true;
7570            Process.killProcessQuiet(pr.pid);
7571            Process.killProcessGroup(pr.info.uid, pr.pid);
7572        }
7573    }
7574
7575    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7576        tr.disposeThumbnail();
7577        mRecentTasks.remove(tr);
7578        tr.closeRecentsChain();
7579        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7580        Intent baseIntent = new Intent(
7581                tr.intent != null ? tr.intent : tr.affinityIntent);
7582        ComponentName component = baseIntent.getComponent();
7583        if (component == null) {
7584            Slog.w(TAG, "Now component for base intent of task: " + tr);
7585            return;
7586        }
7587
7588        // Find any running services associated with this app.
7589        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7590
7591        if (killProcesses) {
7592            // Find any running processes associated with this app.
7593            final String pkg = component.getPackageName();
7594            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7595            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7596            for (int i=0; i<pmap.size(); i++) {
7597                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7598                for (int j=0; j<uids.size(); j++) {
7599                    ProcessRecord proc = uids.valueAt(j);
7600                    if (proc.userId != tr.userId) {
7601                        continue;
7602                    }
7603                    if (!proc.pkgList.containsKey(pkg)) {
7604                        continue;
7605                    }
7606                    procs.add(proc);
7607                }
7608            }
7609
7610            // Kill the running processes.
7611            for (int i=0; i<procs.size(); i++) {
7612                ProcessRecord pr = procs.get(i);
7613                if (pr == mHomeProcess) {
7614                    // Don't kill the home process along with tasks from the same package.
7615                    continue;
7616                }
7617                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7618                    killUnneededProcessLocked(pr, "remove task");
7619                } else {
7620                    pr.waitingToKill = "remove task";
7621                }
7622            }
7623        }
7624    }
7625
7626    /**
7627     * Removes the task with the specified task id.
7628     *
7629     * @param taskId Identifier of the task to be removed.
7630     * @param flags Additional operational flags.  May be 0 or
7631     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7632     * @return Returns true if the given task was found and removed.
7633     */
7634    private boolean removeTaskByIdLocked(int taskId, int flags) {
7635        TaskRecord tr = recentTaskForIdLocked(taskId);
7636        if (tr != null) {
7637            tr.removeTaskActivitiesLocked();
7638            cleanUpRemovedTaskLocked(tr, flags);
7639            if (tr.isPersistable) {
7640                notifyTaskPersisterLocked(tr, true);
7641            }
7642            return true;
7643        }
7644        return false;
7645    }
7646
7647    @Override
7648    public boolean removeTask(int taskId, int flags) {
7649        synchronized (this) {
7650            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7651                    "removeTask()");
7652            long ident = Binder.clearCallingIdentity();
7653            try {
7654                return removeTaskByIdLocked(taskId, flags);
7655            } finally {
7656                Binder.restoreCallingIdentity(ident);
7657            }
7658        }
7659    }
7660
7661    /**
7662     * TODO: Add mController hook
7663     */
7664    @Override
7665    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7666        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7667                "moveTaskToFront()");
7668
7669        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7670        synchronized(this) {
7671            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7672                    Binder.getCallingUid(), "Task to front")) {
7673                ActivityOptions.abort(options);
7674                return;
7675            }
7676            final long origId = Binder.clearCallingIdentity();
7677            try {
7678                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7679                if (task == null) {
7680                    return;
7681                }
7682                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7683                    mStackSupervisor.showLockTaskToast();
7684                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7685                    return;
7686                }
7687                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7688                if (prev != null && prev.isRecentsActivity()) {
7689                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7690                }
7691                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7692            } finally {
7693                Binder.restoreCallingIdentity(origId);
7694            }
7695            ActivityOptions.abort(options);
7696        }
7697    }
7698
7699    @Override
7700    public void moveTaskToBack(int taskId) {
7701        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7702                "moveTaskToBack()");
7703
7704        synchronized(this) {
7705            TaskRecord tr = recentTaskForIdLocked(taskId);
7706            if (tr != null) {
7707                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7708                ActivityStack stack = tr.stack;
7709                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7710                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7711                            Binder.getCallingUid(), "Task to back")) {
7712                        return;
7713                    }
7714                }
7715                final long origId = Binder.clearCallingIdentity();
7716                try {
7717                    stack.moveTaskToBackLocked(taskId, null);
7718                } finally {
7719                    Binder.restoreCallingIdentity(origId);
7720                }
7721            }
7722        }
7723    }
7724
7725    /**
7726     * Moves an activity, and all of the other activities within the same task, to the bottom
7727     * of the history stack.  The activity's order within the task is unchanged.
7728     *
7729     * @param token A reference to the activity we wish to move
7730     * @param nonRoot If false then this only works if the activity is the root
7731     *                of a task; if true it will work for any activity in a task.
7732     * @return Returns true if the move completed, false if not.
7733     */
7734    @Override
7735    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7736        enforceNotIsolatedCaller("moveActivityTaskToBack");
7737        synchronized(this) {
7738            final long origId = Binder.clearCallingIdentity();
7739            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7740            if (taskId >= 0) {
7741                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7742            }
7743            Binder.restoreCallingIdentity(origId);
7744        }
7745        return false;
7746    }
7747
7748    @Override
7749    public void moveTaskBackwards(int task) {
7750        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7751                "moveTaskBackwards()");
7752
7753        synchronized(this) {
7754            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7755                    Binder.getCallingUid(), "Task backwards")) {
7756                return;
7757            }
7758            final long origId = Binder.clearCallingIdentity();
7759            moveTaskBackwardsLocked(task);
7760            Binder.restoreCallingIdentity(origId);
7761        }
7762    }
7763
7764    private final void moveTaskBackwardsLocked(int task) {
7765        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7766    }
7767
7768    @Override
7769    public IBinder getHomeActivityToken() throws RemoteException {
7770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7771                "getHomeActivityToken()");
7772        synchronized (this) {
7773            return mStackSupervisor.getHomeActivityToken();
7774        }
7775    }
7776
7777    @Override
7778    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7779            IActivityContainerCallback callback) throws RemoteException {
7780        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7781                "createActivityContainer()");
7782        synchronized (this) {
7783            if (parentActivityToken == null) {
7784                throw new IllegalArgumentException("parent token must not be null");
7785            }
7786            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7787            if (r == null) {
7788                return null;
7789            }
7790            if (callback == null) {
7791                throw new IllegalArgumentException("callback must not be null");
7792            }
7793            return mStackSupervisor.createActivityContainer(r, callback);
7794        }
7795    }
7796
7797    @Override
7798    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7799        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7800                "deleteActivityContainer()");
7801        synchronized (this) {
7802            mStackSupervisor.deleteActivityContainer(container);
7803        }
7804    }
7805
7806    @Override
7807    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7808            throws RemoteException {
7809        synchronized (this) {
7810            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7811            if (stack != null) {
7812                return stack.mActivityContainer;
7813            }
7814            return null;
7815        }
7816    }
7817
7818    @Override
7819    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7820        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7821                "moveTaskToStack()");
7822        if (stackId == HOME_STACK_ID) {
7823            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7824                    new RuntimeException("here").fillInStackTrace());
7825        }
7826        synchronized (this) {
7827            long ident = Binder.clearCallingIdentity();
7828            try {
7829                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7830                        + stackId + " toTop=" + toTop);
7831                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7832            } finally {
7833                Binder.restoreCallingIdentity(ident);
7834            }
7835        }
7836    }
7837
7838    @Override
7839    public void resizeStack(int stackBoxId, Rect bounds) {
7840        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7841                "resizeStackBox()");
7842        long ident = Binder.clearCallingIdentity();
7843        try {
7844            mWindowManager.resizeStack(stackBoxId, bounds);
7845        } finally {
7846            Binder.restoreCallingIdentity(ident);
7847        }
7848    }
7849
7850    @Override
7851    public List<StackInfo> getAllStackInfos() {
7852        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7853                "getAllStackInfos()");
7854        long ident = Binder.clearCallingIdentity();
7855        try {
7856            synchronized (this) {
7857                return mStackSupervisor.getAllStackInfosLocked();
7858            }
7859        } finally {
7860            Binder.restoreCallingIdentity(ident);
7861        }
7862    }
7863
7864    @Override
7865    public StackInfo getStackInfo(int stackId) {
7866        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7867                "getStackInfo()");
7868        long ident = Binder.clearCallingIdentity();
7869        try {
7870            synchronized (this) {
7871                return mStackSupervisor.getStackInfoLocked(stackId);
7872            }
7873        } finally {
7874            Binder.restoreCallingIdentity(ident);
7875        }
7876    }
7877
7878    @Override
7879    public boolean isInHomeStack(int taskId) {
7880        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7881                "getStackInfo()");
7882        long ident = Binder.clearCallingIdentity();
7883        try {
7884            synchronized (this) {
7885                TaskRecord tr = recentTaskForIdLocked(taskId);
7886                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7887            }
7888        } finally {
7889            Binder.restoreCallingIdentity(ident);
7890        }
7891    }
7892
7893    @Override
7894    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7895        synchronized(this) {
7896            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7897        }
7898    }
7899
7900    private boolean isLockTaskAuthorized(String pkg) {
7901        final DevicePolicyManager dpm = (DevicePolicyManager)
7902                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7903        try {
7904            int uid = mContext.getPackageManager().getPackageUid(pkg,
7905                    Binder.getCallingUserHandle().getIdentifier());
7906            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7907        } catch (NameNotFoundException e) {
7908            return false;
7909        }
7910    }
7911
7912    void startLockTaskMode(TaskRecord task) {
7913        final String pkg;
7914        synchronized (this) {
7915            pkg = task.intent.getComponent().getPackageName();
7916        }
7917        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7918        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7919            final TaskRecord taskRecord = task;
7920            mHandler.post(new Runnable() {
7921                @Override
7922                public void run() {
7923                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7924                }
7925            });
7926            return;
7927        }
7928        long ident = Binder.clearCallingIdentity();
7929        try {
7930            synchronized (this) {
7931                // Since we lost lock on task, make sure it is still there.
7932                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7933                if (task != null) {
7934                    if (!isSystemInitiated
7935                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7936                        throw new IllegalArgumentException("Invalid task, not in foreground");
7937                    }
7938                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7939                }
7940            }
7941        } finally {
7942            Binder.restoreCallingIdentity(ident);
7943        }
7944    }
7945
7946    @Override
7947    public void startLockTaskMode(int taskId) {
7948        final TaskRecord task;
7949        long ident = Binder.clearCallingIdentity();
7950        try {
7951            synchronized (this) {
7952                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7953            }
7954        } finally {
7955            Binder.restoreCallingIdentity(ident);
7956        }
7957        if (task != null) {
7958            startLockTaskMode(task);
7959        }
7960    }
7961
7962    @Override
7963    public void startLockTaskMode(IBinder token) {
7964        final TaskRecord task;
7965        long ident = Binder.clearCallingIdentity();
7966        try {
7967            synchronized (this) {
7968                final ActivityRecord r = ActivityRecord.forToken(token);
7969                if (r == null) {
7970                    return;
7971                }
7972                task = r.task;
7973            }
7974        } finally {
7975            Binder.restoreCallingIdentity(ident);
7976        }
7977        if (task != null) {
7978            startLockTaskMode(task);
7979        }
7980    }
7981
7982    @Override
7983    public void startLockTaskModeOnCurrent() throws RemoteException {
7984        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7985        ActivityRecord r = null;
7986        synchronized (this) {
7987            r = mStackSupervisor.topRunningActivityLocked();
7988        }
7989        startLockTaskMode(r.task);
7990    }
7991
7992    @Override
7993    public void stopLockTaskMode() {
7994        // Verify that the user matches the package of the intent for the TaskRecord
7995        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7996        // and stopLockTaskMode.
7997        final int callingUid = Binder.getCallingUid();
7998        if (callingUid != Process.SYSTEM_UID) {
7999            try {
8000                String pkg =
8001                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8002                int uid = mContext.getPackageManager().getPackageUid(pkg,
8003                        Binder.getCallingUserHandle().getIdentifier());
8004                if (uid != callingUid) {
8005                    throw new SecurityException("Invalid uid, expected " + uid);
8006                }
8007            } catch (NameNotFoundException e) {
8008                Log.d(TAG, "stopLockTaskMode " + e);
8009                return;
8010            }
8011        }
8012        long ident = Binder.clearCallingIdentity();
8013        try {
8014            Log.d(TAG, "stopLockTaskMode");
8015            // Stop lock task
8016            synchronized (this) {
8017                mStackSupervisor.setLockTaskModeLocked(null, false);
8018            }
8019        } finally {
8020            Binder.restoreCallingIdentity(ident);
8021        }
8022    }
8023
8024    @Override
8025    public void stopLockTaskModeOnCurrent() throws RemoteException {
8026        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8027        long ident = Binder.clearCallingIdentity();
8028        try {
8029            stopLockTaskMode();
8030        } finally {
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033    }
8034
8035    @Override
8036    public boolean isInLockTaskMode() {
8037        synchronized (this) {
8038            return mStackSupervisor.isInLockTaskMode();
8039        }
8040    }
8041
8042    // =========================================================
8043    // CONTENT PROVIDERS
8044    // =========================================================
8045
8046    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8047        List<ProviderInfo> providers = null;
8048        try {
8049            providers = AppGlobals.getPackageManager().
8050                queryContentProviders(app.processName, app.uid,
8051                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8052        } catch (RemoteException ex) {
8053        }
8054        if (DEBUG_MU)
8055            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8056        int userId = app.userId;
8057        if (providers != null) {
8058            int N = providers.size();
8059            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8060            for (int i=0; i<N; i++) {
8061                ProviderInfo cpi =
8062                    (ProviderInfo)providers.get(i);
8063                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8064                        cpi.name, cpi.flags);
8065                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8066                    // This is a singleton provider, but a user besides the
8067                    // default user is asking to initialize a process it runs
8068                    // in...  well, no, it doesn't actually run in this process,
8069                    // it runs in the process of the default user.  Get rid of it.
8070                    providers.remove(i);
8071                    N--;
8072                    i--;
8073                    continue;
8074                }
8075
8076                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8077                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8078                if (cpr == null) {
8079                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8080                    mProviderMap.putProviderByClass(comp, cpr);
8081                }
8082                if (DEBUG_MU)
8083                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8084                app.pubProviders.put(cpi.name, cpr);
8085                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8086                    // Don't add this if it is a platform component that is marked
8087                    // to run in multiple processes, because this is actually
8088                    // part of the framework so doesn't make sense to track as a
8089                    // separate apk in the process.
8090                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8091                            mProcessStats);
8092                }
8093                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8094            }
8095        }
8096        return providers;
8097    }
8098
8099    /**
8100     * Check if {@link ProcessRecord} has a possible chance at accessing the
8101     * given {@link ProviderInfo}. Final permission checking is always done
8102     * in {@link ContentProvider}.
8103     */
8104    private final String checkContentProviderPermissionLocked(
8105            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8106        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8107        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8108        boolean checkedGrants = false;
8109        if (checkUser) {
8110            // Looking for cross-user grants before enforcing the typical cross-users permissions
8111            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8112            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8113                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8114                    return null;
8115                }
8116                checkedGrants = true;
8117            }
8118            userId = handleIncomingUser(callingPid, callingUid, userId,
8119                    false, ALLOW_NON_FULL,
8120                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8121            if (userId != tmpTargetUserId) {
8122                // When we actually went to determine the final targer user ID, this ended
8123                // up different than our initial check for the authority.  This is because
8124                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8125                // SELF.  So we need to re-check the grants again.
8126                checkedGrants = false;
8127            }
8128        }
8129        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8130                cpi.applicationInfo.uid, cpi.exported)
8131                == PackageManager.PERMISSION_GRANTED) {
8132            return null;
8133        }
8134        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8135                cpi.applicationInfo.uid, cpi.exported)
8136                == PackageManager.PERMISSION_GRANTED) {
8137            return null;
8138        }
8139
8140        PathPermission[] pps = cpi.pathPermissions;
8141        if (pps != null) {
8142            int i = pps.length;
8143            while (i > 0) {
8144                i--;
8145                PathPermission pp = pps[i];
8146                String pprperm = pp.getReadPermission();
8147                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8148                        cpi.applicationInfo.uid, cpi.exported)
8149                        == PackageManager.PERMISSION_GRANTED) {
8150                    return null;
8151                }
8152                String ppwperm = pp.getWritePermission();
8153                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8154                        cpi.applicationInfo.uid, cpi.exported)
8155                        == PackageManager.PERMISSION_GRANTED) {
8156                    return null;
8157                }
8158            }
8159        }
8160        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8161            return null;
8162        }
8163
8164        String msg;
8165        if (!cpi.exported) {
8166            msg = "Permission Denial: opening provider " + cpi.name
8167                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8168                    + ", uid=" + callingUid + ") that is not exported from uid "
8169                    + cpi.applicationInfo.uid;
8170        } else {
8171            msg = "Permission Denial: opening provider " + cpi.name
8172                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8173                    + ", uid=" + callingUid + ") requires "
8174                    + cpi.readPermission + " or " + cpi.writePermission;
8175        }
8176        Slog.w(TAG, msg);
8177        return msg;
8178    }
8179
8180    /**
8181     * Returns if the ContentProvider has granted a uri to callingUid
8182     */
8183    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8184        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8185        if (perms != null) {
8186            for (int i=perms.size()-1; i>=0; i--) {
8187                GrantUri grantUri = perms.keyAt(i);
8188                if (grantUri.sourceUserId == userId || !checkUser) {
8189                    if (matchesProvider(grantUri.uri, cpi)) {
8190                        return true;
8191                    }
8192                }
8193            }
8194        }
8195        return false;
8196    }
8197
8198    /**
8199     * Returns true if the uri authority is one of the authorities specified in the provider.
8200     */
8201    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8202        String uriAuth = uri.getAuthority();
8203        String cpiAuth = cpi.authority;
8204        if (cpiAuth.indexOf(';') == -1) {
8205            return cpiAuth.equals(uriAuth);
8206        }
8207        String[] cpiAuths = cpiAuth.split(";");
8208        int length = cpiAuths.length;
8209        for (int i = 0; i < length; i++) {
8210            if (cpiAuths[i].equals(uriAuth)) return true;
8211        }
8212        return false;
8213    }
8214
8215    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8216            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8217        if (r != null) {
8218            for (int i=0; i<r.conProviders.size(); i++) {
8219                ContentProviderConnection conn = r.conProviders.get(i);
8220                if (conn.provider == cpr) {
8221                    if (DEBUG_PROVIDER) Slog.v(TAG,
8222                            "Adding provider requested by "
8223                            + r.processName + " from process "
8224                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8225                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8226                    if (stable) {
8227                        conn.stableCount++;
8228                        conn.numStableIncs++;
8229                    } else {
8230                        conn.unstableCount++;
8231                        conn.numUnstableIncs++;
8232                    }
8233                    return conn;
8234                }
8235            }
8236            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8237            if (stable) {
8238                conn.stableCount = 1;
8239                conn.numStableIncs = 1;
8240            } else {
8241                conn.unstableCount = 1;
8242                conn.numUnstableIncs = 1;
8243            }
8244            cpr.connections.add(conn);
8245            r.conProviders.add(conn);
8246            return conn;
8247        }
8248        cpr.addExternalProcessHandleLocked(externalProcessToken);
8249        return null;
8250    }
8251
8252    boolean decProviderCountLocked(ContentProviderConnection conn,
8253            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8254        if (conn != null) {
8255            cpr = conn.provider;
8256            if (DEBUG_PROVIDER) Slog.v(TAG,
8257                    "Removing provider requested by "
8258                    + conn.client.processName + " from process "
8259                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8260                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8261            if (stable) {
8262                conn.stableCount--;
8263            } else {
8264                conn.unstableCount--;
8265            }
8266            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8267                cpr.connections.remove(conn);
8268                conn.client.conProviders.remove(conn);
8269                return true;
8270            }
8271            return false;
8272        }
8273        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8274        return false;
8275    }
8276
8277    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8278            String name, IBinder token, boolean stable, int userId) {
8279        ContentProviderRecord cpr;
8280        ContentProviderConnection conn = null;
8281        ProviderInfo cpi = null;
8282
8283        synchronized(this) {
8284            ProcessRecord r = null;
8285            if (caller != null) {
8286                r = getRecordForAppLocked(caller);
8287                if (r == null) {
8288                    throw new SecurityException(
8289                            "Unable to find app for caller " + caller
8290                          + " (pid=" + Binder.getCallingPid()
8291                          + ") when getting content provider " + name);
8292                }
8293            }
8294
8295            boolean checkCrossUser = true;
8296
8297            // First check if this content provider has been published...
8298            cpr = mProviderMap.getProviderByName(name, userId);
8299            // If that didn't work, check if it exists for user 0 and then
8300            // verify that it's a singleton provider before using it.
8301            if (cpr == null && userId != UserHandle.USER_OWNER) {
8302                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8303                if (cpr != null) {
8304                    cpi = cpr.info;
8305                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8306                            cpi.name, cpi.flags)
8307                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8308                        userId = UserHandle.USER_OWNER;
8309                        checkCrossUser = false;
8310                    } else {
8311                        cpr = null;
8312                        cpi = null;
8313                    }
8314                }
8315            }
8316
8317            boolean providerRunning = cpr != null;
8318            if (providerRunning) {
8319                cpi = cpr.info;
8320                String msg;
8321                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8322                        != null) {
8323                    throw new SecurityException(msg);
8324                }
8325
8326                if (r != null && cpr.canRunHere(r)) {
8327                    // This provider has been published or is in the process
8328                    // of being published...  but it is also allowed to run
8329                    // in the caller's process, so don't make a connection
8330                    // and just let the caller instantiate its own instance.
8331                    ContentProviderHolder holder = cpr.newHolder(null);
8332                    // don't give caller the provider object, it needs
8333                    // to make its own.
8334                    holder.provider = null;
8335                    return holder;
8336                }
8337
8338                final long origId = Binder.clearCallingIdentity();
8339
8340                // In this case the provider instance already exists, so we can
8341                // return it right away.
8342                conn = incProviderCountLocked(r, cpr, token, stable);
8343                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8344                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8345                        // If this is a perceptible app accessing the provider,
8346                        // make sure to count it as being accessed and thus
8347                        // back up on the LRU list.  This is good because
8348                        // content providers are often expensive to start.
8349                        updateLruProcessLocked(cpr.proc, false, null);
8350                    }
8351                }
8352
8353                if (cpr.proc != null) {
8354                    if (false) {
8355                        if (cpr.name.flattenToShortString().equals(
8356                                "com.android.providers.calendar/.CalendarProvider2")) {
8357                            Slog.v(TAG, "****************** KILLING "
8358                                + cpr.name.flattenToShortString());
8359                            Process.killProcess(cpr.proc.pid);
8360                        }
8361                    }
8362                    boolean success = updateOomAdjLocked(cpr.proc);
8363                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8364                    // NOTE: there is still a race here where a signal could be
8365                    // pending on the process even though we managed to update its
8366                    // adj level.  Not sure what to do about this, but at least
8367                    // the race is now smaller.
8368                    if (!success) {
8369                        // Uh oh...  it looks like the provider's process
8370                        // has been killed on us.  We need to wait for a new
8371                        // process to be started, and make sure its death
8372                        // doesn't kill our process.
8373                        Slog.i(TAG,
8374                                "Existing provider " + cpr.name.flattenToShortString()
8375                                + " is crashing; detaching " + r);
8376                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8377                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8378                        if (!lastRef) {
8379                            // This wasn't the last ref our process had on
8380                            // the provider...  we have now been killed, bail.
8381                            return null;
8382                        }
8383                        providerRunning = false;
8384                        conn = null;
8385                    }
8386                }
8387
8388                Binder.restoreCallingIdentity(origId);
8389            }
8390
8391            boolean singleton;
8392            if (!providerRunning) {
8393                try {
8394                    cpi = AppGlobals.getPackageManager().
8395                        resolveContentProvider(name,
8396                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8397                } catch (RemoteException ex) {
8398                }
8399                if (cpi == null) {
8400                    return null;
8401                }
8402                // If the provider is a singleton AND
8403                // (it's a call within the same user || the provider is a
8404                // privileged app)
8405                // Then allow connecting to the singleton provider
8406                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8407                        cpi.name, cpi.flags)
8408                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8409                if (singleton) {
8410                    userId = UserHandle.USER_OWNER;
8411                }
8412                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8413
8414                String msg;
8415                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8416                        != null) {
8417                    throw new SecurityException(msg);
8418                }
8419
8420                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8421                        && !cpi.processName.equals("system")) {
8422                    // If this content provider does not run in the system
8423                    // process, and the system is not yet ready to run other
8424                    // processes, then fail fast instead of hanging.
8425                    throw new IllegalArgumentException(
8426                            "Attempt to launch content provider before system ready");
8427                }
8428
8429                // Make sure that the user who owns this provider is started.  If not,
8430                // we don't want to allow it to run.
8431                if (mStartedUsers.get(userId) == null) {
8432                    Slog.w(TAG, "Unable to launch app "
8433                            + cpi.applicationInfo.packageName + "/"
8434                            + cpi.applicationInfo.uid + " for provider "
8435                            + name + ": user " + userId + " is stopped");
8436                    return null;
8437                }
8438
8439                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8440                cpr = mProviderMap.getProviderByClass(comp, userId);
8441                final boolean firstClass = cpr == null;
8442                if (firstClass) {
8443                    try {
8444                        ApplicationInfo ai =
8445                            AppGlobals.getPackageManager().
8446                                getApplicationInfo(
8447                                        cpi.applicationInfo.packageName,
8448                                        STOCK_PM_FLAGS, userId);
8449                        if (ai == null) {
8450                            Slog.w(TAG, "No package info for content provider "
8451                                    + cpi.name);
8452                            return null;
8453                        }
8454                        ai = getAppInfoForUser(ai, userId);
8455                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8456                    } catch (RemoteException ex) {
8457                        // pm is in same process, this will never happen.
8458                    }
8459                }
8460
8461                if (r != null && cpr.canRunHere(r)) {
8462                    // If this is a multiprocess provider, then just return its
8463                    // info and allow the caller to instantiate it.  Only do
8464                    // this if the provider is the same user as the caller's
8465                    // process, or can run as root (so can be in any process).
8466                    return cpr.newHolder(null);
8467                }
8468
8469                if (DEBUG_PROVIDER) {
8470                    RuntimeException e = new RuntimeException("here");
8471                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8472                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8473                }
8474
8475                // This is single process, and our app is now connecting to it.
8476                // See if we are already in the process of launching this
8477                // provider.
8478                final int N = mLaunchingProviders.size();
8479                int i;
8480                for (i=0; i<N; i++) {
8481                    if (mLaunchingProviders.get(i) == cpr) {
8482                        break;
8483                    }
8484                }
8485
8486                // If the provider is not already being launched, then get it
8487                // started.
8488                if (i >= N) {
8489                    final long origId = Binder.clearCallingIdentity();
8490
8491                    try {
8492                        // Content provider is now in use, its package can't be stopped.
8493                        try {
8494                            AppGlobals.getPackageManager().setPackageStoppedState(
8495                                    cpr.appInfo.packageName, false, userId);
8496                        } catch (RemoteException e) {
8497                        } catch (IllegalArgumentException e) {
8498                            Slog.w(TAG, "Failed trying to unstop package "
8499                                    + cpr.appInfo.packageName + ": " + e);
8500                        }
8501
8502                        // Use existing process if already started
8503                        ProcessRecord proc = getProcessRecordLocked(
8504                                cpi.processName, cpr.appInfo.uid, false);
8505                        if (proc != null && proc.thread != null) {
8506                            if (DEBUG_PROVIDER) {
8507                                Slog.d(TAG, "Installing in existing process " + proc);
8508                            }
8509                            proc.pubProviders.put(cpi.name, cpr);
8510                            try {
8511                                proc.thread.scheduleInstallProvider(cpi);
8512                            } catch (RemoteException e) {
8513                            }
8514                        } else {
8515                            proc = startProcessLocked(cpi.processName,
8516                                    cpr.appInfo, false, 0, "content provider",
8517                                    new ComponentName(cpi.applicationInfo.packageName,
8518                                            cpi.name), false, false, false);
8519                            if (proc == null) {
8520                                Slog.w(TAG, "Unable to launch app "
8521                                        + cpi.applicationInfo.packageName + "/"
8522                                        + cpi.applicationInfo.uid + " for provider "
8523                                        + name + ": process is bad");
8524                                return null;
8525                            }
8526                        }
8527                        cpr.launchingApp = proc;
8528                        mLaunchingProviders.add(cpr);
8529                    } finally {
8530                        Binder.restoreCallingIdentity(origId);
8531                    }
8532                }
8533
8534                // Make sure the provider is published (the same provider class
8535                // may be published under multiple names).
8536                if (firstClass) {
8537                    mProviderMap.putProviderByClass(comp, cpr);
8538                }
8539
8540                mProviderMap.putProviderByName(name, cpr);
8541                conn = incProviderCountLocked(r, cpr, token, stable);
8542                if (conn != null) {
8543                    conn.waiting = true;
8544                }
8545            }
8546        }
8547
8548        // Wait for the provider to be published...
8549        synchronized (cpr) {
8550            while (cpr.provider == null) {
8551                if (cpr.launchingApp == null) {
8552                    Slog.w(TAG, "Unable to launch app "
8553                            + cpi.applicationInfo.packageName + "/"
8554                            + cpi.applicationInfo.uid + " for provider "
8555                            + name + ": launching app became null");
8556                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8557                            UserHandle.getUserId(cpi.applicationInfo.uid),
8558                            cpi.applicationInfo.packageName,
8559                            cpi.applicationInfo.uid, name);
8560                    return null;
8561                }
8562                try {
8563                    if (DEBUG_MU) {
8564                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8565                                + cpr.launchingApp);
8566                    }
8567                    if (conn != null) {
8568                        conn.waiting = true;
8569                    }
8570                    cpr.wait();
8571                } catch (InterruptedException ex) {
8572                } finally {
8573                    if (conn != null) {
8574                        conn.waiting = false;
8575                    }
8576                }
8577            }
8578        }
8579        return cpr != null ? cpr.newHolder(conn) : null;
8580    }
8581
8582    @Override
8583    public final ContentProviderHolder getContentProvider(
8584            IApplicationThread caller, String name, int userId, boolean stable) {
8585        enforceNotIsolatedCaller("getContentProvider");
8586        if (caller == null) {
8587            String msg = "null IApplicationThread when getting content provider "
8588                    + name;
8589            Slog.w(TAG, msg);
8590            throw new SecurityException(msg);
8591        }
8592        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8593        // with cross-user grant.
8594        return getContentProviderImpl(caller, name, null, stable, userId);
8595    }
8596
8597    public ContentProviderHolder getContentProviderExternal(
8598            String name, int userId, IBinder token) {
8599        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8600            "Do not have permission in call getContentProviderExternal()");
8601        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8602                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8603        return getContentProviderExternalUnchecked(name, token, userId);
8604    }
8605
8606    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8607            IBinder token, int userId) {
8608        return getContentProviderImpl(null, name, token, true, userId);
8609    }
8610
8611    /**
8612     * Drop a content provider from a ProcessRecord's bookkeeping
8613     */
8614    public void removeContentProvider(IBinder connection, boolean stable) {
8615        enforceNotIsolatedCaller("removeContentProvider");
8616        long ident = Binder.clearCallingIdentity();
8617        try {
8618            synchronized (this) {
8619                ContentProviderConnection conn;
8620                try {
8621                    conn = (ContentProviderConnection)connection;
8622                } catch (ClassCastException e) {
8623                    String msg ="removeContentProvider: " + connection
8624                            + " not a ContentProviderConnection";
8625                    Slog.w(TAG, msg);
8626                    throw new IllegalArgumentException(msg);
8627                }
8628                if (conn == null) {
8629                    throw new NullPointerException("connection is null");
8630                }
8631                if (decProviderCountLocked(conn, null, null, stable)) {
8632                    updateOomAdjLocked();
8633                }
8634            }
8635        } finally {
8636            Binder.restoreCallingIdentity(ident);
8637        }
8638    }
8639
8640    public void removeContentProviderExternal(String name, IBinder token) {
8641        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8642            "Do not have permission in call removeContentProviderExternal()");
8643        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8644    }
8645
8646    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8647        synchronized (this) {
8648            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8649            if(cpr == null) {
8650                //remove from mProvidersByClass
8651                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8652                return;
8653            }
8654
8655            //update content provider record entry info
8656            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8657            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8658            if (localCpr.hasExternalProcessHandles()) {
8659                if (localCpr.removeExternalProcessHandleLocked(token)) {
8660                    updateOomAdjLocked();
8661                } else {
8662                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8663                            + " with no external reference for token: "
8664                            + token + ".");
8665                }
8666            } else {
8667                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8668                        + " with no external references.");
8669            }
8670        }
8671    }
8672
8673    public final void publishContentProviders(IApplicationThread caller,
8674            List<ContentProviderHolder> providers) {
8675        if (providers == null) {
8676            return;
8677        }
8678
8679        enforceNotIsolatedCaller("publishContentProviders");
8680        synchronized (this) {
8681            final ProcessRecord r = getRecordForAppLocked(caller);
8682            if (DEBUG_MU)
8683                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8684            if (r == null) {
8685                throw new SecurityException(
8686                        "Unable to find app for caller " + caller
8687                      + " (pid=" + Binder.getCallingPid()
8688                      + ") when publishing content providers");
8689            }
8690
8691            final long origId = Binder.clearCallingIdentity();
8692
8693            final int N = providers.size();
8694            for (int i=0; i<N; i++) {
8695                ContentProviderHolder src = providers.get(i);
8696                if (src == null || src.info == null || src.provider == null) {
8697                    continue;
8698                }
8699                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8700                if (DEBUG_MU)
8701                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8702                if (dst != null) {
8703                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8704                    mProviderMap.putProviderByClass(comp, dst);
8705                    String names[] = dst.info.authority.split(";");
8706                    for (int j = 0; j < names.length; j++) {
8707                        mProviderMap.putProviderByName(names[j], dst);
8708                    }
8709
8710                    int NL = mLaunchingProviders.size();
8711                    int j;
8712                    for (j=0; j<NL; j++) {
8713                        if (mLaunchingProviders.get(j) == dst) {
8714                            mLaunchingProviders.remove(j);
8715                            j--;
8716                            NL--;
8717                        }
8718                    }
8719                    synchronized (dst) {
8720                        dst.provider = src.provider;
8721                        dst.proc = r;
8722                        dst.notifyAll();
8723                    }
8724                    updateOomAdjLocked(r);
8725                }
8726            }
8727
8728            Binder.restoreCallingIdentity(origId);
8729        }
8730    }
8731
8732    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8733        ContentProviderConnection conn;
8734        try {
8735            conn = (ContentProviderConnection)connection;
8736        } catch (ClassCastException e) {
8737            String msg ="refContentProvider: " + connection
8738                    + " not a ContentProviderConnection";
8739            Slog.w(TAG, msg);
8740            throw new IllegalArgumentException(msg);
8741        }
8742        if (conn == null) {
8743            throw new NullPointerException("connection is null");
8744        }
8745
8746        synchronized (this) {
8747            if (stable > 0) {
8748                conn.numStableIncs += stable;
8749            }
8750            stable = conn.stableCount + stable;
8751            if (stable < 0) {
8752                throw new IllegalStateException("stableCount < 0: " + stable);
8753            }
8754
8755            if (unstable > 0) {
8756                conn.numUnstableIncs += unstable;
8757            }
8758            unstable = conn.unstableCount + unstable;
8759            if (unstable < 0) {
8760                throw new IllegalStateException("unstableCount < 0: " + unstable);
8761            }
8762
8763            if ((stable+unstable) <= 0) {
8764                throw new IllegalStateException("ref counts can't go to zero here: stable="
8765                        + stable + " unstable=" + unstable);
8766            }
8767            conn.stableCount = stable;
8768            conn.unstableCount = unstable;
8769            return !conn.dead;
8770        }
8771    }
8772
8773    public void unstableProviderDied(IBinder connection) {
8774        ContentProviderConnection conn;
8775        try {
8776            conn = (ContentProviderConnection)connection;
8777        } catch (ClassCastException e) {
8778            String msg ="refContentProvider: " + connection
8779                    + " not a ContentProviderConnection";
8780            Slog.w(TAG, msg);
8781            throw new IllegalArgumentException(msg);
8782        }
8783        if (conn == null) {
8784            throw new NullPointerException("connection is null");
8785        }
8786
8787        // Safely retrieve the content provider associated with the connection.
8788        IContentProvider provider;
8789        synchronized (this) {
8790            provider = conn.provider.provider;
8791        }
8792
8793        if (provider == null) {
8794            // Um, yeah, we're way ahead of you.
8795            return;
8796        }
8797
8798        // Make sure the caller is being honest with us.
8799        if (provider.asBinder().pingBinder()) {
8800            // Er, no, still looks good to us.
8801            synchronized (this) {
8802                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8803                        + " says " + conn + " died, but we don't agree");
8804                return;
8805            }
8806        }
8807
8808        // Well look at that!  It's dead!
8809        synchronized (this) {
8810            if (conn.provider.provider != provider) {
8811                // But something changed...  good enough.
8812                return;
8813            }
8814
8815            ProcessRecord proc = conn.provider.proc;
8816            if (proc == null || proc.thread == null) {
8817                // Seems like the process is already cleaned up.
8818                return;
8819            }
8820
8821            // As far as we're concerned, this is just like receiving a
8822            // death notification...  just a bit prematurely.
8823            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8824                    + ") early provider death");
8825            final long ident = Binder.clearCallingIdentity();
8826            try {
8827                appDiedLocked(proc, proc.pid, proc.thread);
8828            } finally {
8829                Binder.restoreCallingIdentity(ident);
8830            }
8831        }
8832    }
8833
8834    @Override
8835    public void appNotRespondingViaProvider(IBinder connection) {
8836        enforceCallingPermission(
8837                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8838
8839        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8840        if (conn == null) {
8841            Slog.w(TAG, "ContentProviderConnection is null");
8842            return;
8843        }
8844
8845        final ProcessRecord host = conn.provider.proc;
8846        if (host == null) {
8847            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8848            return;
8849        }
8850
8851        final long token = Binder.clearCallingIdentity();
8852        try {
8853            appNotResponding(host, null, null, false, "ContentProvider not responding");
8854        } finally {
8855            Binder.restoreCallingIdentity(token);
8856        }
8857    }
8858
8859    public final void installSystemProviders() {
8860        List<ProviderInfo> providers;
8861        synchronized (this) {
8862            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8863            providers = generateApplicationProvidersLocked(app);
8864            if (providers != null) {
8865                for (int i=providers.size()-1; i>=0; i--) {
8866                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8867                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8868                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8869                                + ": not system .apk");
8870                        providers.remove(i);
8871                    }
8872                }
8873            }
8874        }
8875        if (providers != null) {
8876            mSystemThread.installSystemProviders(providers);
8877        }
8878
8879        mCoreSettingsObserver = new CoreSettingsObserver(this);
8880
8881        //mUsageStatsService.monitorPackages();
8882    }
8883
8884    /**
8885     * Allows app to retrieve the MIME type of a URI without having permission
8886     * to access its content provider.
8887     *
8888     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8889     *
8890     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8891     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8892     */
8893    public String getProviderMimeType(Uri uri, int userId) {
8894        enforceNotIsolatedCaller("getProviderMimeType");
8895        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8896                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8897        final String name = uri.getAuthority();
8898        final long ident = Binder.clearCallingIdentity();
8899        ContentProviderHolder holder = null;
8900
8901        try {
8902            holder = getContentProviderExternalUnchecked(name, null, userId);
8903            if (holder != null) {
8904                return holder.provider.getType(uri);
8905            }
8906        } catch (RemoteException e) {
8907            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8908            return null;
8909        } finally {
8910            if (holder != null) {
8911                removeContentProviderExternalUnchecked(name, null, userId);
8912            }
8913            Binder.restoreCallingIdentity(ident);
8914        }
8915
8916        return null;
8917    }
8918
8919    // =========================================================
8920    // GLOBAL MANAGEMENT
8921    // =========================================================
8922
8923    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8924            boolean isolated) {
8925        String proc = customProcess != null ? customProcess : info.processName;
8926        BatteryStatsImpl.Uid.Proc ps = null;
8927        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8928        int uid = info.uid;
8929        if (isolated) {
8930            int userId = UserHandle.getUserId(uid);
8931            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8932            while (true) {
8933                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8934                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8935                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8936                }
8937                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8938                mNextIsolatedProcessUid++;
8939                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8940                    // No process for this uid, use it.
8941                    break;
8942                }
8943                stepsLeft--;
8944                if (stepsLeft <= 0) {
8945                    return null;
8946                }
8947            }
8948        }
8949        return new ProcessRecord(stats, info, proc, uid);
8950    }
8951
8952    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8953            String abiOverride) {
8954        ProcessRecord app;
8955        if (!isolated) {
8956            app = getProcessRecordLocked(info.processName, info.uid, true);
8957        } else {
8958            app = null;
8959        }
8960
8961        if (app == null) {
8962            app = newProcessRecordLocked(info, null, isolated);
8963            mProcessNames.put(info.processName, app.uid, app);
8964            if (isolated) {
8965                mIsolatedProcesses.put(app.uid, app);
8966            }
8967            updateLruProcessLocked(app, false, null);
8968            updateOomAdjLocked();
8969        }
8970
8971        // This package really, really can not be stopped.
8972        try {
8973            AppGlobals.getPackageManager().setPackageStoppedState(
8974                    info.packageName, false, UserHandle.getUserId(app.uid));
8975        } catch (RemoteException e) {
8976        } catch (IllegalArgumentException e) {
8977            Slog.w(TAG, "Failed trying to unstop package "
8978                    + info.packageName + ": " + e);
8979        }
8980
8981        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8982                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8983            app.persistent = true;
8984            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8985        }
8986        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8987            mPersistentStartingProcesses.add(app);
8988            startProcessLocked(app, "added application", app.processName,
8989                    abiOverride);
8990        }
8991
8992        return app;
8993    }
8994
8995    public void unhandledBack() {
8996        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8997                "unhandledBack()");
8998
8999        synchronized(this) {
9000            final long origId = Binder.clearCallingIdentity();
9001            try {
9002                getFocusedStack().unhandledBackLocked();
9003            } finally {
9004                Binder.restoreCallingIdentity(origId);
9005            }
9006        }
9007    }
9008
9009    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9010        enforceNotIsolatedCaller("openContentUri");
9011        final int userId = UserHandle.getCallingUserId();
9012        String name = uri.getAuthority();
9013        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9014        ParcelFileDescriptor pfd = null;
9015        if (cph != null) {
9016            // We record the binder invoker's uid in thread-local storage before
9017            // going to the content provider to open the file.  Later, in the code
9018            // that handles all permissions checks, we look for this uid and use
9019            // that rather than the Activity Manager's own uid.  The effect is that
9020            // we do the check against the caller's permissions even though it looks
9021            // to the content provider like the Activity Manager itself is making
9022            // the request.
9023            sCallerIdentity.set(new Identity(
9024                    Binder.getCallingPid(), Binder.getCallingUid()));
9025            try {
9026                pfd = cph.provider.openFile(null, uri, "r", null);
9027            } catch (FileNotFoundException e) {
9028                // do nothing; pfd will be returned null
9029            } finally {
9030                // Ensure that whatever happens, we clean up the identity state
9031                sCallerIdentity.remove();
9032            }
9033
9034            // We've got the fd now, so we're done with the provider.
9035            removeContentProviderExternalUnchecked(name, null, userId);
9036        } else {
9037            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9038        }
9039        return pfd;
9040    }
9041
9042    // Actually is sleeping or shutting down or whatever else in the future
9043    // is an inactive state.
9044    public boolean isSleepingOrShuttingDown() {
9045        return mSleeping || mShuttingDown;
9046    }
9047
9048    public boolean isSleeping() {
9049        return mSleeping;
9050    }
9051
9052    void goingToSleep() {
9053        synchronized(this) {
9054            mWentToSleep = true;
9055            updateEventDispatchingLocked();
9056            goToSleepIfNeededLocked();
9057        }
9058    }
9059
9060    void finishRunningVoiceLocked() {
9061        if (mRunningVoice) {
9062            mRunningVoice = false;
9063            goToSleepIfNeededLocked();
9064        }
9065    }
9066
9067    void goToSleepIfNeededLocked() {
9068        if (mWentToSleep && !mRunningVoice) {
9069            if (!mSleeping) {
9070                mSleeping = true;
9071                mStackSupervisor.goingToSleepLocked();
9072
9073                // Initialize the wake times of all processes.
9074                checkExcessivePowerUsageLocked(false);
9075                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9076                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9077                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9078            }
9079        }
9080    }
9081
9082    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9083        mTaskPersister.notify(task, flush);
9084    }
9085
9086    @Override
9087    public boolean shutdown(int timeout) {
9088        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9089                != PackageManager.PERMISSION_GRANTED) {
9090            throw new SecurityException("Requires permission "
9091                    + android.Manifest.permission.SHUTDOWN);
9092        }
9093
9094        boolean timedout = false;
9095
9096        synchronized(this) {
9097            mShuttingDown = true;
9098            updateEventDispatchingLocked();
9099            timedout = mStackSupervisor.shutdownLocked(timeout);
9100        }
9101
9102        mAppOpsService.shutdown();
9103        if (mUsageStatsService != null) {
9104            mUsageStatsService.prepareShutdown();
9105        }
9106        mBatteryStatsService.shutdown();
9107        synchronized (this) {
9108            mProcessStats.shutdownLocked();
9109        }
9110        notifyTaskPersisterLocked(null, true);
9111
9112        return timedout;
9113    }
9114
9115    public final void activitySlept(IBinder token) {
9116        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9117
9118        final long origId = Binder.clearCallingIdentity();
9119
9120        synchronized (this) {
9121            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9122            if (r != null) {
9123                mStackSupervisor.activitySleptLocked(r);
9124            }
9125        }
9126
9127        Binder.restoreCallingIdentity(origId);
9128    }
9129
9130    void logLockScreen(String msg) {
9131        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9132                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9133                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9134                mStackSupervisor.mDismissKeyguardOnNextActivity);
9135    }
9136
9137    private void comeOutOfSleepIfNeededLocked() {
9138        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9139            if (mSleeping) {
9140                mSleeping = false;
9141                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9142            }
9143        }
9144    }
9145
9146    void wakingUp() {
9147        synchronized(this) {
9148            mWentToSleep = false;
9149            updateEventDispatchingLocked();
9150            comeOutOfSleepIfNeededLocked();
9151        }
9152    }
9153
9154    void startRunningVoiceLocked() {
9155        if (!mRunningVoice) {
9156            mRunningVoice = true;
9157            comeOutOfSleepIfNeededLocked();
9158        }
9159    }
9160
9161    private void updateEventDispatchingLocked() {
9162        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9163    }
9164
9165    public void setLockScreenShown(boolean shown) {
9166        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9167                != PackageManager.PERMISSION_GRANTED) {
9168            throw new SecurityException("Requires permission "
9169                    + android.Manifest.permission.DEVICE_POWER);
9170        }
9171
9172        synchronized(this) {
9173            long ident = Binder.clearCallingIdentity();
9174            try {
9175                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9176                mLockScreenShown = shown;
9177                comeOutOfSleepIfNeededLocked();
9178            } finally {
9179                Binder.restoreCallingIdentity(ident);
9180            }
9181        }
9182    }
9183
9184    @Override
9185    public void stopAppSwitches() {
9186        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9187                != PackageManager.PERMISSION_GRANTED) {
9188            throw new SecurityException("Requires permission "
9189                    + android.Manifest.permission.STOP_APP_SWITCHES);
9190        }
9191
9192        synchronized(this) {
9193            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9194                    + APP_SWITCH_DELAY_TIME;
9195            mDidAppSwitch = false;
9196            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9197            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9198            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9199        }
9200    }
9201
9202    public void resumeAppSwitches() {
9203        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9204                != PackageManager.PERMISSION_GRANTED) {
9205            throw new SecurityException("Requires permission "
9206                    + android.Manifest.permission.STOP_APP_SWITCHES);
9207        }
9208
9209        synchronized(this) {
9210            // Note that we don't execute any pending app switches... we will
9211            // let those wait until either the timeout, or the next start
9212            // activity request.
9213            mAppSwitchesAllowedTime = 0;
9214        }
9215    }
9216
9217    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9218            String name) {
9219        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9220            return true;
9221        }
9222
9223        final int perm = checkComponentPermission(
9224                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9225                callingUid, -1, true);
9226        if (perm == PackageManager.PERMISSION_GRANTED) {
9227            return true;
9228        }
9229
9230        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9231        return false;
9232    }
9233
9234    public void setDebugApp(String packageName, boolean waitForDebugger,
9235            boolean persistent) {
9236        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9237                "setDebugApp()");
9238
9239        long ident = Binder.clearCallingIdentity();
9240        try {
9241            // Note that this is not really thread safe if there are multiple
9242            // callers into it at the same time, but that's not a situation we
9243            // care about.
9244            if (persistent) {
9245                final ContentResolver resolver = mContext.getContentResolver();
9246                Settings.Global.putString(
9247                    resolver, Settings.Global.DEBUG_APP,
9248                    packageName);
9249                Settings.Global.putInt(
9250                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9251                    waitForDebugger ? 1 : 0);
9252            }
9253
9254            synchronized (this) {
9255                if (!persistent) {
9256                    mOrigDebugApp = mDebugApp;
9257                    mOrigWaitForDebugger = mWaitForDebugger;
9258                }
9259                mDebugApp = packageName;
9260                mWaitForDebugger = waitForDebugger;
9261                mDebugTransient = !persistent;
9262                if (packageName != null) {
9263                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9264                            false, UserHandle.USER_ALL, "set debug app");
9265                }
9266            }
9267        } finally {
9268            Binder.restoreCallingIdentity(ident);
9269        }
9270    }
9271
9272    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9273        synchronized (this) {
9274            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9275            if (!isDebuggable) {
9276                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9277                    throw new SecurityException("Process not debuggable: " + app.packageName);
9278                }
9279            }
9280
9281            mOpenGlTraceApp = processName;
9282        }
9283    }
9284
9285    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9286            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9287        synchronized (this) {
9288            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9289            if (!isDebuggable) {
9290                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9291                    throw new SecurityException("Process not debuggable: " + app.packageName);
9292                }
9293            }
9294            mProfileApp = processName;
9295            mProfileFile = profileFile;
9296            if (mProfileFd != null) {
9297                try {
9298                    mProfileFd.close();
9299                } catch (IOException e) {
9300                }
9301                mProfileFd = null;
9302            }
9303            mProfileFd = profileFd;
9304            mProfileType = 0;
9305            mAutoStopProfiler = autoStopProfiler;
9306        }
9307    }
9308
9309    @Override
9310    public void setAlwaysFinish(boolean enabled) {
9311        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9312                "setAlwaysFinish()");
9313
9314        Settings.Global.putInt(
9315                mContext.getContentResolver(),
9316                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9317
9318        synchronized (this) {
9319            mAlwaysFinishActivities = enabled;
9320        }
9321    }
9322
9323    @Override
9324    public void setActivityController(IActivityController controller) {
9325        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9326                "setActivityController()");
9327        synchronized (this) {
9328            mController = controller;
9329            Watchdog.getInstance().setActivityController(controller);
9330        }
9331    }
9332
9333    @Override
9334    public void setUserIsMonkey(boolean userIsMonkey) {
9335        synchronized (this) {
9336            synchronized (mPidsSelfLocked) {
9337                final int callingPid = Binder.getCallingPid();
9338                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9339                if (precessRecord == null) {
9340                    throw new SecurityException("Unknown process: " + callingPid);
9341                }
9342                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9343                    throw new SecurityException("Only an instrumentation process "
9344                            + "with a UiAutomation can call setUserIsMonkey");
9345                }
9346            }
9347            mUserIsMonkey = userIsMonkey;
9348        }
9349    }
9350
9351    @Override
9352    public boolean isUserAMonkey() {
9353        synchronized (this) {
9354            // If there is a controller also implies the user is a monkey.
9355            return (mUserIsMonkey || mController != null);
9356        }
9357    }
9358
9359    public void requestBugReport() {
9360        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9361        SystemProperties.set("ctl.start", "bugreport");
9362    }
9363
9364    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9365        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9366    }
9367
9368    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9369        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9370            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9371        }
9372        return KEY_DISPATCHING_TIMEOUT;
9373    }
9374
9375    @Override
9376    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9377        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9378                != PackageManager.PERMISSION_GRANTED) {
9379            throw new SecurityException("Requires permission "
9380                    + android.Manifest.permission.FILTER_EVENTS);
9381        }
9382        ProcessRecord proc;
9383        long timeout;
9384        synchronized (this) {
9385            synchronized (mPidsSelfLocked) {
9386                proc = mPidsSelfLocked.get(pid);
9387            }
9388            timeout = getInputDispatchingTimeoutLocked(proc);
9389        }
9390
9391        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9392            return -1;
9393        }
9394
9395        return timeout;
9396    }
9397
9398    /**
9399     * Handle input dispatching timeouts.
9400     * Returns whether input dispatching should be aborted or not.
9401     */
9402    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9403            final ActivityRecord activity, final ActivityRecord parent,
9404            final boolean aboveSystem, String reason) {
9405        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9406                != PackageManager.PERMISSION_GRANTED) {
9407            throw new SecurityException("Requires permission "
9408                    + android.Manifest.permission.FILTER_EVENTS);
9409        }
9410
9411        final String annotation;
9412        if (reason == null) {
9413            annotation = "Input dispatching timed out";
9414        } else {
9415            annotation = "Input dispatching timed out (" + reason + ")";
9416        }
9417
9418        if (proc != null) {
9419            synchronized (this) {
9420                if (proc.debugging) {
9421                    return false;
9422                }
9423
9424                if (mDidDexOpt) {
9425                    // Give more time since we were dexopting.
9426                    mDidDexOpt = false;
9427                    return false;
9428                }
9429
9430                if (proc.instrumentationClass != null) {
9431                    Bundle info = new Bundle();
9432                    info.putString("shortMsg", "keyDispatchingTimedOut");
9433                    info.putString("longMsg", annotation);
9434                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9435                    return true;
9436                }
9437            }
9438            mHandler.post(new Runnable() {
9439                @Override
9440                public void run() {
9441                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9442                }
9443            });
9444        }
9445
9446        return true;
9447    }
9448
9449    public Bundle getAssistContextExtras(int requestType) {
9450        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9451                "getAssistContextExtras()");
9452        PendingAssistExtras pae;
9453        Bundle extras = new Bundle();
9454        synchronized (this) {
9455            ActivityRecord activity = getFocusedStack().mResumedActivity;
9456            if (activity == null) {
9457                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9458                return null;
9459            }
9460            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9461            if (activity.app == null || activity.app.thread == null) {
9462                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9463                return extras;
9464            }
9465            if (activity.app.pid == Binder.getCallingPid()) {
9466                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9467                return extras;
9468            }
9469            pae = new PendingAssistExtras(activity);
9470            try {
9471                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9472                        requestType);
9473                mPendingAssistExtras.add(pae);
9474                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9475            } catch (RemoteException e) {
9476                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9477                return extras;
9478            }
9479        }
9480        synchronized (pae) {
9481            while (!pae.haveResult) {
9482                try {
9483                    pae.wait();
9484                } catch (InterruptedException e) {
9485                }
9486            }
9487            if (pae.result != null) {
9488                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9489            }
9490        }
9491        synchronized (this) {
9492            mPendingAssistExtras.remove(pae);
9493            mHandler.removeCallbacks(pae);
9494        }
9495        return extras;
9496    }
9497
9498    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9499        PendingAssistExtras pae = (PendingAssistExtras)token;
9500        synchronized (pae) {
9501            pae.result = extras;
9502            pae.haveResult = true;
9503            pae.notifyAll();
9504        }
9505    }
9506
9507    public void registerProcessObserver(IProcessObserver observer) {
9508        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9509                "registerProcessObserver()");
9510        synchronized (this) {
9511            mProcessObservers.register(observer);
9512        }
9513    }
9514
9515    @Override
9516    public void unregisterProcessObserver(IProcessObserver observer) {
9517        synchronized (this) {
9518            mProcessObservers.unregister(observer);
9519        }
9520    }
9521
9522    @Override
9523    public boolean convertFromTranslucent(IBinder token) {
9524        final long origId = Binder.clearCallingIdentity();
9525        try {
9526            synchronized (this) {
9527                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9528                if (r == null) {
9529                    return false;
9530                }
9531                if (r.changeWindowTranslucency(true)) {
9532                    mWindowManager.setAppFullscreen(token, true);
9533                    r.task.stack.releaseMediaResources();
9534                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9535                    return true;
9536                }
9537                return false;
9538            }
9539        } finally {
9540            Binder.restoreCallingIdentity(origId);
9541        }
9542    }
9543
9544    @Override
9545    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9546        final long origId = Binder.clearCallingIdentity();
9547        try {
9548            synchronized (this) {
9549                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9550                if (r == null) {
9551                    return false;
9552                }
9553                if (r.changeWindowTranslucency(false)) {
9554                    r.task.stack.convertToTranslucent(r, options);
9555                    mWindowManager.setAppFullscreen(token, false);
9556                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9557                    return true;
9558                } else {
9559                    r.task.stack.mReturningActivityOptions = options;
9560                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9561                    return false;
9562                }
9563            }
9564        } finally {
9565            Binder.restoreCallingIdentity(origId);
9566        }
9567    }
9568
9569    @Override
9570    public boolean setMediaPlaying(IBinder token, boolean playing) {
9571        final long origId = Binder.clearCallingIdentity();
9572        try {
9573            synchronized (this) {
9574                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9575                if (r != null) {
9576                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9577                }
9578            }
9579            return false;
9580        } finally {
9581            Binder.restoreCallingIdentity(origId);
9582        }
9583    }
9584
9585    @Override
9586    public boolean isBackgroundMediaPlaying(IBinder token) {
9587        final long origId = Binder.clearCallingIdentity();
9588        try {
9589            synchronized (this) {
9590                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9591                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9592                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9593                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9594                return playing;
9595            }
9596        } finally {
9597            Binder.restoreCallingIdentity(origId);
9598        }
9599    }
9600
9601    @Override
9602    public ActivityOptions getActivityOptions(IBinder token) {
9603        final long origId = Binder.clearCallingIdentity();
9604        try {
9605            synchronized (this) {
9606                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9607                if (r != null) {
9608                    final ActivityOptions activityOptions = r.pendingOptions;
9609                    r.pendingOptions = null;
9610                    return activityOptions;
9611                }
9612                return null;
9613            }
9614        } finally {
9615            Binder.restoreCallingIdentity(origId);
9616        }
9617    }
9618
9619    @Override
9620    public void setImmersive(IBinder token, boolean immersive) {
9621        synchronized(this) {
9622            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9623            if (r == null) {
9624                throw new IllegalArgumentException();
9625            }
9626            r.immersive = immersive;
9627
9628            // update associated state if we're frontmost
9629            if (r == mFocusedActivity) {
9630                if (DEBUG_IMMERSIVE) {
9631                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9632                }
9633                applyUpdateLockStateLocked(r);
9634            }
9635        }
9636    }
9637
9638    @Override
9639    public boolean isImmersive(IBinder token) {
9640        synchronized (this) {
9641            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9642            if (r == null) {
9643                throw new IllegalArgumentException();
9644            }
9645            return r.immersive;
9646        }
9647    }
9648
9649    public boolean isTopActivityImmersive() {
9650        enforceNotIsolatedCaller("startActivity");
9651        synchronized (this) {
9652            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9653            return (r != null) ? r.immersive : false;
9654        }
9655    }
9656
9657    @Override
9658    public boolean isTopOfTask(IBinder token) {
9659        synchronized (this) {
9660            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9661            if (r == null) {
9662                throw new IllegalArgumentException();
9663            }
9664            return r.task.getTopActivity() == r;
9665        }
9666    }
9667
9668    public final void enterSafeMode() {
9669        synchronized(this) {
9670            // It only makes sense to do this before the system is ready
9671            // and started launching other packages.
9672            if (!mSystemReady) {
9673                try {
9674                    AppGlobals.getPackageManager().enterSafeMode();
9675                } catch (RemoteException e) {
9676                }
9677            }
9678
9679            mSafeMode = true;
9680        }
9681    }
9682
9683    public final void showSafeModeOverlay() {
9684        View v = LayoutInflater.from(mContext).inflate(
9685                com.android.internal.R.layout.safe_mode, null);
9686        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9687        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9688        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9689        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9690        lp.gravity = Gravity.BOTTOM | Gravity.START;
9691        lp.format = v.getBackground().getOpacity();
9692        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9693                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9694        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9695        ((WindowManager)mContext.getSystemService(
9696                Context.WINDOW_SERVICE)).addView(v, lp);
9697    }
9698
9699    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9700        if (!(sender instanceof PendingIntentRecord)) {
9701            return;
9702        }
9703        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9704        synchronized (stats) {
9705            if (mBatteryStatsService.isOnBattery()) {
9706                mBatteryStatsService.enforceCallingPermission();
9707                PendingIntentRecord rec = (PendingIntentRecord)sender;
9708                int MY_UID = Binder.getCallingUid();
9709                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9710                BatteryStatsImpl.Uid.Pkg pkg =
9711                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9712                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9713                pkg.incWakeupsLocked();
9714            }
9715        }
9716    }
9717
9718    public boolean killPids(int[] pids, String pReason, boolean secure) {
9719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9720            throw new SecurityException("killPids only available to the system");
9721        }
9722        String reason = (pReason == null) ? "Unknown" : pReason;
9723        // XXX Note: don't acquire main activity lock here, because the window
9724        // manager calls in with its locks held.
9725
9726        boolean killed = false;
9727        synchronized (mPidsSelfLocked) {
9728            int[] types = new int[pids.length];
9729            int worstType = 0;
9730            for (int i=0; i<pids.length; i++) {
9731                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9732                if (proc != null) {
9733                    int type = proc.setAdj;
9734                    types[i] = type;
9735                    if (type > worstType) {
9736                        worstType = type;
9737                    }
9738                }
9739            }
9740
9741            // If the worst oom_adj is somewhere in the cached proc LRU range,
9742            // then constrain it so we will kill all cached procs.
9743            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9744                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9745                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9746            }
9747
9748            // If this is not a secure call, don't let it kill processes that
9749            // are important.
9750            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9751                worstType = ProcessList.SERVICE_ADJ;
9752            }
9753
9754            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9755            for (int i=0; i<pids.length; i++) {
9756                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9757                if (proc == null) {
9758                    continue;
9759                }
9760                int adj = proc.setAdj;
9761                if (adj >= worstType && !proc.killedByAm) {
9762                    killUnneededProcessLocked(proc, reason);
9763                    killed = true;
9764                }
9765            }
9766        }
9767        return killed;
9768    }
9769
9770    @Override
9771    public void killUid(int uid, String reason) {
9772        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9773            throw new SecurityException("killUid only available to the system");
9774        }
9775        synchronized (this) {
9776            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9777                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9778                    reason != null ? reason : "kill uid");
9779        }
9780    }
9781
9782    @Override
9783    public boolean killProcessesBelowForeground(String reason) {
9784        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9785            throw new SecurityException("killProcessesBelowForeground() only available to system");
9786        }
9787
9788        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9789    }
9790
9791    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9792        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9793            throw new SecurityException("killProcessesBelowAdj() only available to system");
9794        }
9795
9796        boolean killed = false;
9797        synchronized (mPidsSelfLocked) {
9798            final int size = mPidsSelfLocked.size();
9799            for (int i = 0; i < size; i++) {
9800                final int pid = mPidsSelfLocked.keyAt(i);
9801                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9802                if (proc == null) continue;
9803
9804                final int adj = proc.setAdj;
9805                if (adj > belowAdj && !proc.killedByAm) {
9806                    killUnneededProcessLocked(proc, reason);
9807                    killed = true;
9808                }
9809            }
9810        }
9811        return killed;
9812    }
9813
9814    @Override
9815    public void hang(final IBinder who, boolean allowRestart) {
9816        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9817                != PackageManager.PERMISSION_GRANTED) {
9818            throw new SecurityException("Requires permission "
9819                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9820        }
9821
9822        final IBinder.DeathRecipient death = new DeathRecipient() {
9823            @Override
9824            public void binderDied() {
9825                synchronized (this) {
9826                    notifyAll();
9827                }
9828            }
9829        };
9830
9831        try {
9832            who.linkToDeath(death, 0);
9833        } catch (RemoteException e) {
9834            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9835            return;
9836        }
9837
9838        synchronized (this) {
9839            Watchdog.getInstance().setAllowRestart(allowRestart);
9840            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9841            synchronized (death) {
9842                while (who.isBinderAlive()) {
9843                    try {
9844                        death.wait();
9845                    } catch (InterruptedException e) {
9846                    }
9847                }
9848            }
9849            Watchdog.getInstance().setAllowRestart(true);
9850        }
9851    }
9852
9853    @Override
9854    public void restart() {
9855        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9856                != PackageManager.PERMISSION_GRANTED) {
9857            throw new SecurityException("Requires permission "
9858                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9859        }
9860
9861        Log.i(TAG, "Sending shutdown broadcast...");
9862
9863        BroadcastReceiver br = new BroadcastReceiver() {
9864            @Override public void onReceive(Context context, Intent intent) {
9865                // Now the broadcast is done, finish up the low-level shutdown.
9866                Log.i(TAG, "Shutting down activity manager...");
9867                shutdown(10000);
9868                Log.i(TAG, "Shutdown complete, restarting!");
9869                Process.killProcess(Process.myPid());
9870                System.exit(10);
9871            }
9872        };
9873
9874        // First send the high-level shut down broadcast.
9875        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9876        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9877        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9878        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9879        mContext.sendOrderedBroadcastAsUser(intent,
9880                UserHandle.ALL, null, br, mHandler, 0, null, null);
9881        */
9882        br.onReceive(mContext, intent);
9883    }
9884
9885    private long getLowRamTimeSinceIdle(long now) {
9886        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9887    }
9888
9889    @Override
9890    public void performIdleMaintenance() {
9891        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9892                != PackageManager.PERMISSION_GRANTED) {
9893            throw new SecurityException("Requires permission "
9894                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9895        }
9896
9897        synchronized (this) {
9898            final long now = SystemClock.uptimeMillis();
9899            final long timeSinceLastIdle = now - mLastIdleTime;
9900            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9901            mLastIdleTime = now;
9902            mLowRamTimeSinceLastIdle = 0;
9903            if (mLowRamStartTime != 0) {
9904                mLowRamStartTime = now;
9905            }
9906
9907            StringBuilder sb = new StringBuilder(128);
9908            sb.append("Idle maintenance over ");
9909            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9910            sb.append(" low RAM for ");
9911            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9912            Slog.i(TAG, sb.toString());
9913
9914            // If at least 1/3 of our time since the last idle period has been spent
9915            // with RAM low, then we want to kill processes.
9916            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9917
9918            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9919                ProcessRecord proc = mLruProcesses.get(i);
9920                if (proc.notCachedSinceIdle) {
9921                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9922                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9923                        if (doKilling && proc.initialIdlePss != 0
9924                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9925                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9926                                    + " from " + proc.initialIdlePss + ")");
9927                        }
9928                    }
9929                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9930                    proc.notCachedSinceIdle = true;
9931                    proc.initialIdlePss = 0;
9932                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9933                            isSleeping(), now);
9934                }
9935            }
9936
9937            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9938            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9939        }
9940    }
9941
9942    private void retrieveSettings() {
9943        final ContentResolver resolver = mContext.getContentResolver();
9944        String debugApp = Settings.Global.getString(
9945            resolver, Settings.Global.DEBUG_APP);
9946        boolean waitForDebugger = Settings.Global.getInt(
9947            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9948        boolean alwaysFinishActivities = Settings.Global.getInt(
9949            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9950        boolean forceRtl = Settings.Global.getInt(
9951                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9952        // Transfer any global setting for forcing RTL layout, into a System Property
9953        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9954
9955        Configuration configuration = new Configuration();
9956        Settings.System.getConfiguration(resolver, configuration);
9957        if (forceRtl) {
9958            // This will take care of setting the correct layout direction flags
9959            configuration.setLayoutDirection(configuration.locale);
9960        }
9961
9962        synchronized (this) {
9963            mDebugApp = mOrigDebugApp = debugApp;
9964            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9965            mAlwaysFinishActivities = alwaysFinishActivities;
9966            // This happens before any activities are started, so we can
9967            // change mConfiguration in-place.
9968            updateConfigurationLocked(configuration, null, false, true);
9969            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9970        }
9971    }
9972
9973    public boolean testIsSystemReady() {
9974        // no need to synchronize(this) just to read & return the value
9975        return mSystemReady;
9976    }
9977
9978    private static File getCalledPreBootReceiversFile() {
9979        File dataDir = Environment.getDataDirectory();
9980        File systemDir = new File(dataDir, "system");
9981        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9982        return fname;
9983    }
9984
9985    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9986        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9987        File file = getCalledPreBootReceiversFile();
9988        FileInputStream fis = null;
9989        try {
9990            fis = new FileInputStream(file);
9991            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9992            int fvers = dis.readInt();
9993            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
9994                String vers = dis.readUTF();
9995                String codename = dis.readUTF();
9996                String build = dis.readUTF();
9997                if (android.os.Build.VERSION.RELEASE.equals(vers)
9998                        && android.os.Build.VERSION.CODENAME.equals(codename)
9999                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10000                    int num = dis.readInt();
10001                    while (num > 0) {
10002                        num--;
10003                        String pkg = dis.readUTF();
10004                        String cls = dis.readUTF();
10005                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10006                    }
10007                }
10008            }
10009        } catch (FileNotFoundException e) {
10010        } catch (IOException e) {
10011            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10012        } finally {
10013            if (fis != null) {
10014                try {
10015                    fis.close();
10016                } catch (IOException e) {
10017                }
10018            }
10019        }
10020        return lastDoneReceivers;
10021    }
10022
10023    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10024        File file = getCalledPreBootReceiversFile();
10025        FileOutputStream fos = null;
10026        DataOutputStream dos = null;
10027        try {
10028            fos = new FileOutputStream(file);
10029            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10030            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10031            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10032            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10033            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10034            dos.writeInt(list.size());
10035            for (int i=0; i<list.size(); i++) {
10036                dos.writeUTF(list.get(i).getPackageName());
10037                dos.writeUTF(list.get(i).getClassName());
10038            }
10039        } catch (IOException e) {
10040            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10041            file.delete();
10042        } finally {
10043            FileUtils.sync(fos);
10044            if (dos != null) {
10045                try {
10046                    dos.close();
10047                } catch (IOException e) {
10048                    // TODO Auto-generated catch block
10049                    e.printStackTrace();
10050                }
10051            }
10052        }
10053    }
10054
10055    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10056            ArrayList<ComponentName> doneReceivers, int userId) {
10057        boolean waitingUpdate = false;
10058        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10059        List<ResolveInfo> ris = null;
10060        try {
10061            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10062                    intent, null, 0, userId);
10063        } catch (RemoteException e) {
10064        }
10065        if (ris != null) {
10066            for (int i=ris.size()-1; i>=0; i--) {
10067                if ((ris.get(i).activityInfo.applicationInfo.flags
10068                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10069                    ris.remove(i);
10070                }
10071            }
10072            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10073
10074            // For User 0, load the version number. When delivering to a new user, deliver
10075            // to all receivers.
10076            if (userId == UserHandle.USER_OWNER) {
10077                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10078                for (int i=0; i<ris.size(); i++) {
10079                    ActivityInfo ai = ris.get(i).activityInfo;
10080                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10081                    if (lastDoneReceivers.contains(comp)) {
10082                        // We already did the pre boot receiver for this app with the current
10083                        // platform version, so don't do it again...
10084                        ris.remove(i);
10085                        i--;
10086                        // ...however, do keep it as one that has been done, so we don't
10087                        // forget about it when rewriting the file of last done receivers.
10088                        doneReceivers.add(comp);
10089                    }
10090                }
10091            }
10092
10093            // If primary user, send broadcast to all available users, else just to userId
10094            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10095                    : new int[] { userId };
10096            for (int i = 0; i < ris.size(); i++) {
10097                ActivityInfo ai = ris.get(i).activityInfo;
10098                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10099                doneReceivers.add(comp);
10100                intent.setComponent(comp);
10101                for (int j=0; j<users.length; j++) {
10102                    IIntentReceiver finisher = null;
10103                    // On last receiver and user, set up a completion callback
10104                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10105                        finisher = new IIntentReceiver.Stub() {
10106                            public void performReceive(Intent intent, int resultCode,
10107                                    String data, Bundle extras, boolean ordered,
10108                                    boolean sticky, int sendingUser) {
10109                                // The raw IIntentReceiver interface is called
10110                                // with the AM lock held, so redispatch to
10111                                // execute our code without the lock.
10112                                mHandler.post(onFinishCallback);
10113                            }
10114                        };
10115                    }
10116                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10117                            + " for user " + users[j]);
10118                    broadcastIntentLocked(null, null, intent, null, finisher,
10119                            0, null, null, null, AppOpsManager.OP_NONE,
10120                            true, false, MY_PID, Process.SYSTEM_UID,
10121                            users[j]);
10122                    if (finisher != null) {
10123                        waitingUpdate = true;
10124                    }
10125                }
10126            }
10127        }
10128
10129        return waitingUpdate;
10130    }
10131
10132    public void systemReady(final Runnable goingCallback) {
10133        synchronized(this) {
10134            if (mSystemReady) {
10135                // If we're done calling all the receivers, run the next "boot phase" passed in
10136                // by the SystemServer
10137                if (goingCallback != null) {
10138                    goingCallback.run();
10139                }
10140                return;
10141            }
10142
10143            // Make sure we have the current profile info, since it is needed for
10144            // security checks.
10145            updateCurrentProfileIdsLocked();
10146
10147            if (mRecentTasks == null) {
10148                mRecentTasks = mTaskPersister.restoreTasksLocked();
10149                if (!mRecentTasks.isEmpty()) {
10150                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10151                }
10152                mTaskPersister.startPersisting();
10153            }
10154
10155            // Check to see if there are any update receivers to run.
10156            if (!mDidUpdate) {
10157                if (mWaitingUpdate) {
10158                    return;
10159                }
10160                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10161                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10162                    public void run() {
10163                        synchronized (ActivityManagerService.this) {
10164                            mDidUpdate = true;
10165                        }
10166                        writeLastDonePreBootReceivers(doneReceivers);
10167                        showBootMessage(mContext.getText(
10168                                R.string.android_upgrading_complete),
10169                                false);
10170                        systemReady(goingCallback);
10171                    }
10172                }, doneReceivers, UserHandle.USER_OWNER);
10173
10174                if (mWaitingUpdate) {
10175                    return;
10176                }
10177                mDidUpdate = true;
10178            }
10179
10180            mAppOpsService.systemReady();
10181            mSystemReady = true;
10182        }
10183
10184        ArrayList<ProcessRecord> procsToKill = null;
10185        synchronized(mPidsSelfLocked) {
10186            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10187                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10188                if (!isAllowedWhileBooting(proc.info)){
10189                    if (procsToKill == null) {
10190                        procsToKill = new ArrayList<ProcessRecord>();
10191                    }
10192                    procsToKill.add(proc);
10193                }
10194            }
10195        }
10196
10197        synchronized(this) {
10198            if (procsToKill != null) {
10199                for (int i=procsToKill.size()-1; i>=0; i--) {
10200                    ProcessRecord proc = procsToKill.get(i);
10201                    Slog.i(TAG, "Removing system update proc: " + proc);
10202                    removeProcessLocked(proc, true, false, "system update done");
10203                }
10204            }
10205
10206            // Now that we have cleaned up any update processes, we
10207            // are ready to start launching real processes and know that
10208            // we won't trample on them any more.
10209            mProcessesReady = true;
10210        }
10211
10212        Slog.i(TAG, "System now ready");
10213        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10214            SystemClock.uptimeMillis());
10215
10216        synchronized(this) {
10217            // Make sure we have no pre-ready processes sitting around.
10218
10219            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10220                ResolveInfo ri = mContext.getPackageManager()
10221                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10222                                STOCK_PM_FLAGS);
10223                CharSequence errorMsg = null;
10224                if (ri != null) {
10225                    ActivityInfo ai = ri.activityInfo;
10226                    ApplicationInfo app = ai.applicationInfo;
10227                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10228                        mTopAction = Intent.ACTION_FACTORY_TEST;
10229                        mTopData = null;
10230                        mTopComponent = new ComponentName(app.packageName,
10231                                ai.name);
10232                    } else {
10233                        errorMsg = mContext.getResources().getText(
10234                                com.android.internal.R.string.factorytest_not_system);
10235                    }
10236                } else {
10237                    errorMsg = mContext.getResources().getText(
10238                            com.android.internal.R.string.factorytest_no_action);
10239                }
10240                if (errorMsg != null) {
10241                    mTopAction = null;
10242                    mTopData = null;
10243                    mTopComponent = null;
10244                    Message msg = Message.obtain();
10245                    msg.what = SHOW_FACTORY_ERROR_MSG;
10246                    msg.getData().putCharSequence("msg", errorMsg);
10247                    mHandler.sendMessage(msg);
10248                }
10249            }
10250        }
10251
10252        retrieveSettings();
10253
10254        synchronized (this) {
10255            readGrantedUriPermissionsLocked();
10256        }
10257
10258        if (goingCallback != null) goingCallback.run();
10259
10260        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10261                Integer.toString(mCurrentUserId), mCurrentUserId);
10262        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10263                Integer.toString(mCurrentUserId), mCurrentUserId);
10264        mSystemServiceManager.startUser(mCurrentUserId);
10265
10266        synchronized (this) {
10267            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10268                try {
10269                    List apps = AppGlobals.getPackageManager().
10270                        getPersistentApplications(STOCK_PM_FLAGS);
10271                    if (apps != null) {
10272                        int N = apps.size();
10273                        int i;
10274                        for (i=0; i<N; i++) {
10275                            ApplicationInfo info
10276                                = (ApplicationInfo)apps.get(i);
10277                            if (info != null &&
10278                                    !info.packageName.equals("android")) {
10279                                addAppLocked(info, false, null /* ABI override */);
10280                            }
10281                        }
10282                    }
10283                } catch (RemoteException ex) {
10284                    // pm is in same process, this will never happen.
10285                }
10286            }
10287
10288            // Start up initial activity.
10289            mBooting = true;
10290
10291            try {
10292                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10293                    Message msg = Message.obtain();
10294                    msg.what = SHOW_UID_ERROR_MSG;
10295                    mHandler.sendMessage(msg);
10296                }
10297            } catch (RemoteException e) {
10298            }
10299
10300            long ident = Binder.clearCallingIdentity();
10301            try {
10302                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10304                        | Intent.FLAG_RECEIVER_FOREGROUND);
10305                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10306                broadcastIntentLocked(null, null, intent,
10307                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10308                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10309                intent = new Intent(Intent.ACTION_USER_STARTING);
10310                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10311                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10312                broadcastIntentLocked(null, null, intent,
10313                        null, new IIntentReceiver.Stub() {
10314                            @Override
10315                            public void performReceive(Intent intent, int resultCode, String data,
10316                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10317                                    throws RemoteException {
10318                            }
10319                        }, 0, null, null,
10320                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10321                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10322            } catch (Throwable t) {
10323                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10324            } finally {
10325                Binder.restoreCallingIdentity(ident);
10326            }
10327            mStackSupervisor.resumeTopActivitiesLocked();
10328            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10329        }
10330    }
10331
10332    private boolean makeAppCrashingLocked(ProcessRecord app,
10333            String shortMsg, String longMsg, String stackTrace) {
10334        app.crashing = true;
10335        app.crashingReport = generateProcessError(app,
10336                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10337        startAppProblemLocked(app);
10338        app.stopFreezingAllLocked();
10339        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10340    }
10341
10342    private void makeAppNotRespondingLocked(ProcessRecord app,
10343            String activity, String shortMsg, String longMsg) {
10344        app.notResponding = true;
10345        app.notRespondingReport = generateProcessError(app,
10346                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10347                activity, shortMsg, longMsg, null);
10348        startAppProblemLocked(app);
10349        app.stopFreezingAllLocked();
10350    }
10351
10352    /**
10353     * Generate a process error record, suitable for attachment to a ProcessRecord.
10354     *
10355     * @param app The ProcessRecord in which the error occurred.
10356     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10357     *                      ActivityManager.AppErrorStateInfo
10358     * @param activity The activity associated with the crash, if known.
10359     * @param shortMsg Short message describing the crash.
10360     * @param longMsg Long message describing the crash.
10361     * @param stackTrace Full crash stack trace, may be null.
10362     *
10363     * @return Returns a fully-formed AppErrorStateInfo record.
10364     */
10365    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10366            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10367        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10368
10369        report.condition = condition;
10370        report.processName = app.processName;
10371        report.pid = app.pid;
10372        report.uid = app.info.uid;
10373        report.tag = activity;
10374        report.shortMsg = shortMsg;
10375        report.longMsg = longMsg;
10376        report.stackTrace = stackTrace;
10377
10378        return report;
10379    }
10380
10381    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10382        synchronized (this) {
10383            app.crashing = false;
10384            app.crashingReport = null;
10385            app.notResponding = false;
10386            app.notRespondingReport = null;
10387            if (app.anrDialog == fromDialog) {
10388                app.anrDialog = null;
10389            }
10390            if (app.waitDialog == fromDialog) {
10391                app.waitDialog = null;
10392            }
10393            if (app.pid > 0 && app.pid != MY_PID) {
10394                handleAppCrashLocked(app, null, null, null);
10395                killUnneededProcessLocked(app, "user request after error");
10396            }
10397        }
10398    }
10399
10400    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10401            String stackTrace) {
10402        long now = SystemClock.uptimeMillis();
10403
10404        Long crashTime;
10405        if (!app.isolated) {
10406            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10407        } else {
10408            crashTime = null;
10409        }
10410        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10411            // This process loses!
10412            Slog.w(TAG, "Process " + app.info.processName
10413                    + " has crashed too many times: killing!");
10414            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10415                    app.userId, app.info.processName, app.uid);
10416            mStackSupervisor.handleAppCrashLocked(app);
10417            if (!app.persistent) {
10418                // We don't want to start this process again until the user
10419                // explicitly does so...  but for persistent process, we really
10420                // need to keep it running.  If a persistent process is actually
10421                // repeatedly crashing, then badness for everyone.
10422                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10423                        app.info.processName);
10424                if (!app.isolated) {
10425                    // XXX We don't have a way to mark isolated processes
10426                    // as bad, since they don't have a peristent identity.
10427                    mBadProcesses.put(app.info.processName, app.uid,
10428                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10429                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10430                }
10431                app.bad = true;
10432                app.removed = true;
10433                // Don't let services in this process be restarted and potentially
10434                // annoy the user repeatedly.  Unless it is persistent, since those
10435                // processes run critical code.
10436                removeProcessLocked(app, false, false, "crash");
10437                mStackSupervisor.resumeTopActivitiesLocked();
10438                return false;
10439            }
10440            mStackSupervisor.resumeTopActivitiesLocked();
10441        } else {
10442            mStackSupervisor.finishTopRunningActivityLocked(app);
10443        }
10444
10445        // Bump up the crash count of any services currently running in the proc.
10446        for (int i=app.services.size()-1; i>=0; i--) {
10447            // Any services running in the application need to be placed
10448            // back in the pending list.
10449            ServiceRecord sr = app.services.valueAt(i);
10450            sr.crashCount++;
10451        }
10452
10453        // If the crashing process is what we consider to be the "home process" and it has been
10454        // replaced by a third-party app, clear the package preferred activities from packages
10455        // with a home activity running in the process to prevent a repeatedly crashing app
10456        // from blocking the user to manually clear the list.
10457        final ArrayList<ActivityRecord> activities = app.activities;
10458        if (app == mHomeProcess && activities.size() > 0
10459                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10460            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10461                final ActivityRecord r = activities.get(activityNdx);
10462                if (r.isHomeActivity()) {
10463                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10464                    try {
10465                        ActivityThread.getPackageManager()
10466                                .clearPackagePreferredActivities(r.packageName);
10467                    } catch (RemoteException c) {
10468                        // pm is in same process, this will never happen.
10469                    }
10470                }
10471            }
10472        }
10473
10474        if (!app.isolated) {
10475            // XXX Can't keep track of crash times for isolated processes,
10476            // because they don't have a perisistent identity.
10477            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10478        }
10479
10480        return true;
10481    }
10482
10483    void startAppProblemLocked(ProcessRecord app) {
10484        if (app.userId == mCurrentUserId) {
10485            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10486                    mContext, app.info.packageName, app.info.flags);
10487        } else {
10488            // If this app is not running under the current user, then we
10489            // can't give it a report button because that would require
10490            // launching the report UI under a different user.
10491            app.errorReportReceiver = null;
10492        }
10493        skipCurrentReceiverLocked(app);
10494    }
10495
10496    void skipCurrentReceiverLocked(ProcessRecord app) {
10497        for (BroadcastQueue queue : mBroadcastQueues) {
10498            queue.skipCurrentReceiverLocked(app);
10499        }
10500    }
10501
10502    /**
10503     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10504     * The application process will exit immediately after this call returns.
10505     * @param app object of the crashing app, null for the system server
10506     * @param crashInfo describing the exception
10507     */
10508    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10509        ProcessRecord r = findAppProcess(app, "Crash");
10510        final String processName = app == null ? "system_server"
10511                : (r == null ? "unknown" : r.processName);
10512
10513        handleApplicationCrashInner("crash", r, processName, crashInfo);
10514    }
10515
10516    /* Native crash reporting uses this inner version because it needs to be somewhat
10517     * decoupled from the AM-managed cleanup lifecycle
10518     */
10519    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10520            ApplicationErrorReport.CrashInfo crashInfo) {
10521        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10522                UserHandle.getUserId(Binder.getCallingUid()), processName,
10523                r == null ? -1 : r.info.flags,
10524                crashInfo.exceptionClassName,
10525                crashInfo.exceptionMessage,
10526                crashInfo.throwFileName,
10527                crashInfo.throwLineNumber);
10528
10529        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10530
10531        crashApplication(r, crashInfo);
10532    }
10533
10534    public void handleApplicationStrictModeViolation(
10535            IBinder app,
10536            int violationMask,
10537            StrictMode.ViolationInfo info) {
10538        ProcessRecord r = findAppProcess(app, "StrictMode");
10539        if (r == null) {
10540            return;
10541        }
10542
10543        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10544            Integer stackFingerprint = info.hashCode();
10545            boolean logIt = true;
10546            synchronized (mAlreadyLoggedViolatedStacks) {
10547                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10548                    logIt = false;
10549                    // TODO: sub-sample into EventLog for these, with
10550                    // the info.durationMillis?  Then we'd get
10551                    // the relative pain numbers, without logging all
10552                    // the stack traces repeatedly.  We'd want to do
10553                    // likewise in the client code, which also does
10554                    // dup suppression, before the Binder call.
10555                } else {
10556                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10557                        mAlreadyLoggedViolatedStacks.clear();
10558                    }
10559                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10560                }
10561            }
10562            if (logIt) {
10563                logStrictModeViolationToDropBox(r, info);
10564            }
10565        }
10566
10567        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10568            AppErrorResult result = new AppErrorResult();
10569            synchronized (this) {
10570                final long origId = Binder.clearCallingIdentity();
10571
10572                Message msg = Message.obtain();
10573                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10574                HashMap<String, Object> data = new HashMap<String, Object>();
10575                data.put("result", result);
10576                data.put("app", r);
10577                data.put("violationMask", violationMask);
10578                data.put("info", info);
10579                msg.obj = data;
10580                mHandler.sendMessage(msg);
10581
10582                Binder.restoreCallingIdentity(origId);
10583            }
10584            int res = result.get();
10585            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10586        }
10587    }
10588
10589    // Depending on the policy in effect, there could be a bunch of
10590    // these in quick succession so we try to batch these together to
10591    // minimize disk writes, number of dropbox entries, and maximize
10592    // compression, by having more fewer, larger records.
10593    private void logStrictModeViolationToDropBox(
10594            ProcessRecord process,
10595            StrictMode.ViolationInfo info) {
10596        if (info == null) {
10597            return;
10598        }
10599        final boolean isSystemApp = process == null ||
10600                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10601                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10602        final String processName = process == null ? "unknown" : process.processName;
10603        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10604        final DropBoxManager dbox = (DropBoxManager)
10605                mContext.getSystemService(Context.DROPBOX_SERVICE);
10606
10607        // Exit early if the dropbox isn't configured to accept this report type.
10608        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10609
10610        boolean bufferWasEmpty;
10611        boolean needsFlush;
10612        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10613        synchronized (sb) {
10614            bufferWasEmpty = sb.length() == 0;
10615            appendDropBoxProcessHeaders(process, processName, sb);
10616            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10617            sb.append("System-App: ").append(isSystemApp).append("\n");
10618            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10619            if (info.violationNumThisLoop != 0) {
10620                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10621            }
10622            if (info.numAnimationsRunning != 0) {
10623                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10624            }
10625            if (info.broadcastIntentAction != null) {
10626                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10627            }
10628            if (info.durationMillis != -1) {
10629                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10630            }
10631            if (info.numInstances != -1) {
10632                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10633            }
10634            if (info.tags != null) {
10635                for (String tag : info.tags) {
10636                    sb.append("Span-Tag: ").append(tag).append("\n");
10637                }
10638            }
10639            sb.append("\n");
10640            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10641                sb.append(info.crashInfo.stackTrace);
10642            }
10643            sb.append("\n");
10644
10645            // Only buffer up to ~64k.  Various logging bits truncate
10646            // things at 128k.
10647            needsFlush = (sb.length() > 64 * 1024);
10648        }
10649
10650        // Flush immediately if the buffer's grown too large, or this
10651        // is a non-system app.  Non-system apps are isolated with a
10652        // different tag & policy and not batched.
10653        //
10654        // Batching is useful during internal testing with
10655        // StrictMode settings turned up high.  Without batching,
10656        // thousands of separate files could be created on boot.
10657        if (!isSystemApp || needsFlush) {
10658            new Thread("Error dump: " + dropboxTag) {
10659                @Override
10660                public void run() {
10661                    String report;
10662                    synchronized (sb) {
10663                        report = sb.toString();
10664                        sb.delete(0, sb.length());
10665                        sb.trimToSize();
10666                    }
10667                    if (report.length() != 0) {
10668                        dbox.addText(dropboxTag, report);
10669                    }
10670                }
10671            }.start();
10672            return;
10673        }
10674
10675        // System app batching:
10676        if (!bufferWasEmpty) {
10677            // An existing dropbox-writing thread is outstanding, so
10678            // we don't need to start it up.  The existing thread will
10679            // catch the buffer appends we just did.
10680            return;
10681        }
10682
10683        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10684        // (After this point, we shouldn't access AMS internal data structures.)
10685        new Thread("Error dump: " + dropboxTag) {
10686            @Override
10687            public void run() {
10688                // 5 second sleep to let stacks arrive and be batched together
10689                try {
10690                    Thread.sleep(5000);  // 5 seconds
10691                } catch (InterruptedException e) {}
10692
10693                String errorReport;
10694                synchronized (mStrictModeBuffer) {
10695                    errorReport = mStrictModeBuffer.toString();
10696                    if (errorReport.length() == 0) {
10697                        return;
10698                    }
10699                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10700                    mStrictModeBuffer.trimToSize();
10701                }
10702                dbox.addText(dropboxTag, errorReport);
10703            }
10704        }.start();
10705    }
10706
10707    /**
10708     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10709     * @param app object of the crashing app, null for the system server
10710     * @param tag reported by the caller
10711     * @param crashInfo describing the context of the error
10712     * @return true if the process should exit immediately (WTF is fatal)
10713     */
10714    public boolean handleApplicationWtf(IBinder app, String tag,
10715            ApplicationErrorReport.CrashInfo crashInfo) {
10716        ProcessRecord r = findAppProcess(app, "WTF");
10717        final String processName = app == null ? "system_server"
10718                : (r == null ? "unknown" : r.processName);
10719
10720        EventLog.writeEvent(EventLogTags.AM_WTF,
10721                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10722                processName,
10723                r == null ? -1 : r.info.flags,
10724                tag, crashInfo.exceptionMessage);
10725
10726        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10727
10728        if (r != null && r.pid != Process.myPid() &&
10729                Settings.Global.getInt(mContext.getContentResolver(),
10730                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10731            crashApplication(r, crashInfo);
10732            return true;
10733        } else {
10734            return false;
10735        }
10736    }
10737
10738    /**
10739     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10740     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10741     */
10742    private ProcessRecord findAppProcess(IBinder app, String reason) {
10743        if (app == null) {
10744            return null;
10745        }
10746
10747        synchronized (this) {
10748            final int NP = mProcessNames.getMap().size();
10749            for (int ip=0; ip<NP; ip++) {
10750                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10751                final int NA = apps.size();
10752                for (int ia=0; ia<NA; ia++) {
10753                    ProcessRecord p = apps.valueAt(ia);
10754                    if (p.thread != null && p.thread.asBinder() == app) {
10755                        return p;
10756                    }
10757                }
10758            }
10759
10760            Slog.w(TAG, "Can't find mystery application for " + reason
10761                    + " from pid=" + Binder.getCallingPid()
10762                    + " uid=" + Binder.getCallingUid() + ": " + app);
10763            return null;
10764        }
10765    }
10766
10767    /**
10768     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10769     * to append various headers to the dropbox log text.
10770     */
10771    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10772            StringBuilder sb) {
10773        // Watchdog thread ends up invoking this function (with
10774        // a null ProcessRecord) to add the stack file to dropbox.
10775        // Do not acquire a lock on this (am) in such cases, as it
10776        // could cause a potential deadlock, if and when watchdog
10777        // is invoked due to unavailability of lock on am and it
10778        // would prevent watchdog from killing system_server.
10779        if (process == null) {
10780            sb.append("Process: ").append(processName).append("\n");
10781            return;
10782        }
10783        // Note: ProcessRecord 'process' is guarded by the service
10784        // instance.  (notably process.pkgList, which could otherwise change
10785        // concurrently during execution of this method)
10786        synchronized (this) {
10787            sb.append("Process: ").append(processName).append("\n");
10788            int flags = process.info.flags;
10789            IPackageManager pm = AppGlobals.getPackageManager();
10790            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10791            for (int ip=0; ip<process.pkgList.size(); ip++) {
10792                String pkg = process.pkgList.keyAt(ip);
10793                sb.append("Package: ").append(pkg);
10794                try {
10795                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10796                    if (pi != null) {
10797                        sb.append(" v").append(pi.versionCode);
10798                        if (pi.versionName != null) {
10799                            sb.append(" (").append(pi.versionName).append(")");
10800                        }
10801                    }
10802                } catch (RemoteException e) {
10803                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10804                }
10805                sb.append("\n");
10806            }
10807        }
10808    }
10809
10810    private static String processClass(ProcessRecord process) {
10811        if (process == null || process.pid == MY_PID) {
10812            return "system_server";
10813        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10814            return "system_app";
10815        } else {
10816            return "data_app";
10817        }
10818    }
10819
10820    /**
10821     * Write a description of an error (crash, WTF, ANR) to the drop box.
10822     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10823     * @param process which caused the error, null means the system server
10824     * @param activity which triggered the error, null if unknown
10825     * @param parent activity related to the error, null if unknown
10826     * @param subject line related to the error, null if absent
10827     * @param report in long form describing the error, null if absent
10828     * @param logFile to include in the report, null if none
10829     * @param crashInfo giving an application stack trace, null if absent
10830     */
10831    public void addErrorToDropBox(String eventType,
10832            ProcessRecord process, String processName, ActivityRecord activity,
10833            ActivityRecord parent, String subject,
10834            final String report, final File logFile,
10835            final ApplicationErrorReport.CrashInfo crashInfo) {
10836        // NOTE -- this must never acquire the ActivityManagerService lock,
10837        // otherwise the watchdog may be prevented from resetting the system.
10838
10839        final String dropboxTag = processClass(process) + "_" + eventType;
10840        final DropBoxManager dbox = (DropBoxManager)
10841                mContext.getSystemService(Context.DROPBOX_SERVICE);
10842
10843        // Exit early if the dropbox isn't configured to accept this report type.
10844        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10845
10846        final StringBuilder sb = new StringBuilder(1024);
10847        appendDropBoxProcessHeaders(process, processName, sb);
10848        if (activity != null) {
10849            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10850        }
10851        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10852            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10853        }
10854        if (parent != null && parent != activity) {
10855            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10856        }
10857        if (subject != null) {
10858            sb.append("Subject: ").append(subject).append("\n");
10859        }
10860        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10861        if (Debug.isDebuggerConnected()) {
10862            sb.append("Debugger: Connected\n");
10863        }
10864        sb.append("\n");
10865
10866        // Do the rest in a worker thread to avoid blocking the caller on I/O
10867        // (After this point, we shouldn't access AMS internal data structures.)
10868        Thread worker = new Thread("Error dump: " + dropboxTag) {
10869            @Override
10870            public void run() {
10871                if (report != null) {
10872                    sb.append(report);
10873                }
10874                if (logFile != null) {
10875                    try {
10876                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10877                                    "\n\n[[TRUNCATED]]"));
10878                    } catch (IOException e) {
10879                        Slog.e(TAG, "Error reading " + logFile, e);
10880                    }
10881                }
10882                if (crashInfo != null && crashInfo.stackTrace != null) {
10883                    sb.append(crashInfo.stackTrace);
10884                }
10885
10886                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10887                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10888                if (lines > 0) {
10889                    sb.append("\n");
10890
10891                    // Merge several logcat streams, and take the last N lines
10892                    InputStreamReader input = null;
10893                    try {
10894                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10895                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10896                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10897
10898                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10899                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10900                        input = new InputStreamReader(logcat.getInputStream());
10901
10902                        int num;
10903                        char[] buf = new char[8192];
10904                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10905                    } catch (IOException e) {
10906                        Slog.e(TAG, "Error running logcat", e);
10907                    } finally {
10908                        if (input != null) try { input.close(); } catch (IOException e) {}
10909                    }
10910                }
10911
10912                dbox.addText(dropboxTag, sb.toString());
10913            }
10914        };
10915
10916        if (process == null) {
10917            // If process is null, we are being called from some internal code
10918            // and may be about to die -- run this synchronously.
10919            worker.run();
10920        } else {
10921            worker.start();
10922        }
10923    }
10924
10925    /**
10926     * Bring up the "unexpected error" dialog box for a crashing app.
10927     * Deal with edge cases (intercepts from instrumented applications,
10928     * ActivityController, error intent receivers, that sort of thing).
10929     * @param r the application crashing
10930     * @param crashInfo describing the failure
10931     */
10932    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10933        long timeMillis = System.currentTimeMillis();
10934        String shortMsg = crashInfo.exceptionClassName;
10935        String longMsg = crashInfo.exceptionMessage;
10936        String stackTrace = crashInfo.stackTrace;
10937        if (shortMsg != null && longMsg != null) {
10938            longMsg = shortMsg + ": " + longMsg;
10939        } else if (shortMsg != null) {
10940            longMsg = shortMsg;
10941        }
10942
10943        AppErrorResult result = new AppErrorResult();
10944        synchronized (this) {
10945            if (mController != null) {
10946                try {
10947                    String name = r != null ? r.processName : null;
10948                    int pid = r != null ? r.pid : Binder.getCallingPid();
10949                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10950                    if (!mController.appCrashed(name, pid,
10951                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10952                        Slog.w(TAG, "Force-killing crashed app " + name
10953                                + " at watcher's request");
10954                        Process.killProcess(pid);
10955                        if (r != null) {
10956                            Process.killProcessGroup(uid, pid);
10957                        }
10958                        return;
10959                    }
10960                } catch (RemoteException e) {
10961                    mController = null;
10962                    Watchdog.getInstance().setActivityController(null);
10963                }
10964            }
10965
10966            final long origId = Binder.clearCallingIdentity();
10967
10968            // If this process is running instrumentation, finish it.
10969            if (r != null && r.instrumentationClass != null) {
10970                Slog.w(TAG, "Error in app " + r.processName
10971                      + " running instrumentation " + r.instrumentationClass + ":");
10972                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10973                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10974                Bundle info = new Bundle();
10975                info.putString("shortMsg", shortMsg);
10976                info.putString("longMsg", longMsg);
10977                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10978                Binder.restoreCallingIdentity(origId);
10979                return;
10980            }
10981
10982            // If we can't identify the process or it's already exceeded its crash quota,
10983            // quit right away without showing a crash dialog.
10984            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10985                Binder.restoreCallingIdentity(origId);
10986                return;
10987            }
10988
10989            Message msg = Message.obtain();
10990            msg.what = SHOW_ERROR_MSG;
10991            HashMap data = new HashMap();
10992            data.put("result", result);
10993            data.put("app", r);
10994            msg.obj = data;
10995            mHandler.sendMessage(msg);
10996
10997            Binder.restoreCallingIdentity(origId);
10998        }
10999
11000        int res = result.get();
11001
11002        Intent appErrorIntent = null;
11003        synchronized (this) {
11004            if (r != null && !r.isolated) {
11005                // XXX Can't keep track of crash time for isolated processes,
11006                // since they don't have a persistent identity.
11007                mProcessCrashTimes.put(r.info.processName, r.uid,
11008                        SystemClock.uptimeMillis());
11009            }
11010            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11011                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11012            }
11013        }
11014
11015        if (appErrorIntent != null) {
11016            try {
11017                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11018            } catch (ActivityNotFoundException e) {
11019                Slog.w(TAG, "bug report receiver dissappeared", e);
11020            }
11021        }
11022    }
11023
11024    Intent createAppErrorIntentLocked(ProcessRecord r,
11025            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11026        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11027        if (report == null) {
11028            return null;
11029        }
11030        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11031        result.setComponent(r.errorReportReceiver);
11032        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11033        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11034        return result;
11035    }
11036
11037    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11038            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11039        if (r.errorReportReceiver == null) {
11040            return null;
11041        }
11042
11043        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11044            return null;
11045        }
11046
11047        ApplicationErrorReport report = new ApplicationErrorReport();
11048        report.packageName = r.info.packageName;
11049        report.installerPackageName = r.errorReportReceiver.getPackageName();
11050        report.processName = r.processName;
11051        report.time = timeMillis;
11052        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11053
11054        if (r.crashing || r.forceCrashReport) {
11055            report.type = ApplicationErrorReport.TYPE_CRASH;
11056            report.crashInfo = crashInfo;
11057        } else if (r.notResponding) {
11058            report.type = ApplicationErrorReport.TYPE_ANR;
11059            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11060
11061            report.anrInfo.activity = r.notRespondingReport.tag;
11062            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11063            report.anrInfo.info = r.notRespondingReport.longMsg;
11064        }
11065
11066        return report;
11067    }
11068
11069    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11070        enforceNotIsolatedCaller("getProcessesInErrorState");
11071        // assume our apps are happy - lazy create the list
11072        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11073
11074        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11075                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11076        int userId = UserHandle.getUserId(Binder.getCallingUid());
11077
11078        synchronized (this) {
11079
11080            // iterate across all processes
11081            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11082                ProcessRecord app = mLruProcesses.get(i);
11083                if (!allUsers && app.userId != userId) {
11084                    continue;
11085                }
11086                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11087                    // This one's in trouble, so we'll generate a report for it
11088                    // crashes are higher priority (in case there's a crash *and* an anr)
11089                    ActivityManager.ProcessErrorStateInfo report = null;
11090                    if (app.crashing) {
11091                        report = app.crashingReport;
11092                    } else if (app.notResponding) {
11093                        report = app.notRespondingReport;
11094                    }
11095
11096                    if (report != null) {
11097                        if (errList == null) {
11098                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11099                        }
11100                        errList.add(report);
11101                    } else {
11102                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11103                                " crashing = " + app.crashing +
11104                                " notResponding = " + app.notResponding);
11105                    }
11106                }
11107            }
11108        }
11109
11110        return errList;
11111    }
11112
11113    static int procStateToImportance(int procState, int memAdj,
11114            ActivityManager.RunningAppProcessInfo currApp) {
11115        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11116        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11117            currApp.lru = memAdj;
11118        } else {
11119            currApp.lru = 0;
11120        }
11121        return imp;
11122    }
11123
11124    private void fillInProcMemInfo(ProcessRecord app,
11125            ActivityManager.RunningAppProcessInfo outInfo) {
11126        outInfo.pid = app.pid;
11127        outInfo.uid = app.info.uid;
11128        if (mHeavyWeightProcess == app) {
11129            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11130        }
11131        if (app.persistent) {
11132            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11133        }
11134        if (app.activities.size() > 0) {
11135            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11136        }
11137        outInfo.lastTrimLevel = app.trimMemoryLevel;
11138        int adj = app.curAdj;
11139        int procState = app.curProcState;
11140        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11141        outInfo.importanceReasonCode = app.adjTypeCode;
11142        outInfo.processState = app.curProcState;
11143    }
11144
11145    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11146        enforceNotIsolatedCaller("getRunningAppProcesses");
11147        // Lazy instantiation of list
11148        List<ActivityManager.RunningAppProcessInfo> runList = null;
11149        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11150                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11151        int userId = UserHandle.getUserId(Binder.getCallingUid());
11152        synchronized (this) {
11153            // Iterate across all processes
11154            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11155                ProcessRecord app = mLruProcesses.get(i);
11156                if (!allUsers && app.userId != userId) {
11157                    continue;
11158                }
11159                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11160                    // Generate process state info for running application
11161                    ActivityManager.RunningAppProcessInfo currApp =
11162                        new ActivityManager.RunningAppProcessInfo(app.processName,
11163                                app.pid, app.getPackageList());
11164                    fillInProcMemInfo(app, currApp);
11165                    if (app.adjSource instanceof ProcessRecord) {
11166                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11167                        currApp.importanceReasonImportance =
11168                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11169                                        app.adjSourceProcState);
11170                    } else if (app.adjSource instanceof ActivityRecord) {
11171                        ActivityRecord r = (ActivityRecord)app.adjSource;
11172                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11173                    }
11174                    if (app.adjTarget instanceof ComponentName) {
11175                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11176                    }
11177                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11178                    //        + " lru=" + currApp.lru);
11179                    if (runList == null) {
11180                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11181                    }
11182                    runList.add(currApp);
11183                }
11184            }
11185        }
11186        return runList;
11187    }
11188
11189    public List<ApplicationInfo> getRunningExternalApplications() {
11190        enforceNotIsolatedCaller("getRunningExternalApplications");
11191        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11192        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11193        if (runningApps != null && runningApps.size() > 0) {
11194            Set<String> extList = new HashSet<String>();
11195            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11196                if (app.pkgList != null) {
11197                    for (String pkg : app.pkgList) {
11198                        extList.add(pkg);
11199                    }
11200                }
11201            }
11202            IPackageManager pm = AppGlobals.getPackageManager();
11203            for (String pkg : extList) {
11204                try {
11205                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11206                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11207                        retList.add(info);
11208                    }
11209                } catch (RemoteException e) {
11210                }
11211            }
11212        }
11213        return retList;
11214    }
11215
11216    @Override
11217    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11218        enforceNotIsolatedCaller("getMyMemoryState");
11219        synchronized (this) {
11220            ProcessRecord proc;
11221            synchronized (mPidsSelfLocked) {
11222                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11223            }
11224            fillInProcMemInfo(proc, outInfo);
11225        }
11226    }
11227
11228    @Override
11229    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11230        if (checkCallingPermission(android.Manifest.permission.DUMP)
11231                != PackageManager.PERMISSION_GRANTED) {
11232            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11233                    + Binder.getCallingPid()
11234                    + ", uid=" + Binder.getCallingUid()
11235                    + " without permission "
11236                    + android.Manifest.permission.DUMP);
11237            return;
11238        }
11239
11240        boolean dumpAll = false;
11241        boolean dumpClient = false;
11242        String dumpPackage = null;
11243
11244        int opti = 0;
11245        while (opti < args.length) {
11246            String opt = args[opti];
11247            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11248                break;
11249            }
11250            opti++;
11251            if ("-a".equals(opt)) {
11252                dumpAll = true;
11253            } else if ("-c".equals(opt)) {
11254                dumpClient = true;
11255            } else if ("-h".equals(opt)) {
11256                pw.println("Activity manager dump options:");
11257                pw.println("  [-a] [-c] [-h] [cmd] ...");
11258                pw.println("  cmd may be one of:");
11259                pw.println("    a[ctivities]: activity stack state");
11260                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11261                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11262                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11263                pw.println("    o[om]: out of memory management");
11264                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11265                pw.println("    provider [COMP_SPEC]: provider client-side state");
11266                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11267                pw.println("    service [COMP_SPEC]: service client-side state");
11268                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11269                pw.println("    all: dump all activities");
11270                pw.println("    top: dump the top activity");
11271                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11272                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11273                pw.println("    a partial substring in a component name, a");
11274                pw.println("    hex object identifier.");
11275                pw.println("  -a: include all available server state.");
11276                pw.println("  -c: include client state.");
11277                return;
11278            } else {
11279                pw.println("Unknown argument: " + opt + "; use -h for help");
11280            }
11281        }
11282
11283        long origId = Binder.clearCallingIdentity();
11284        boolean more = false;
11285        // Is the caller requesting to dump a particular piece of data?
11286        if (opti < args.length) {
11287            String cmd = args[opti];
11288            opti++;
11289            if ("activities".equals(cmd) || "a".equals(cmd)) {
11290                synchronized (this) {
11291                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11292                }
11293            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11294                String[] newArgs;
11295                String name;
11296                if (opti >= args.length) {
11297                    name = null;
11298                    newArgs = EMPTY_STRING_ARRAY;
11299                } else {
11300                    name = args[opti];
11301                    opti++;
11302                    newArgs = new String[args.length - opti];
11303                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11304                            args.length - opti);
11305                }
11306                synchronized (this) {
11307                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11308                }
11309            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11310                String[] newArgs;
11311                String name;
11312                if (opti >= args.length) {
11313                    name = null;
11314                    newArgs = EMPTY_STRING_ARRAY;
11315                } else {
11316                    name = args[opti];
11317                    opti++;
11318                    newArgs = new String[args.length - opti];
11319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11320                            args.length - opti);
11321                }
11322                synchronized (this) {
11323                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11324                }
11325            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11326                String[] newArgs;
11327                String name;
11328                if (opti >= args.length) {
11329                    name = null;
11330                    newArgs = EMPTY_STRING_ARRAY;
11331                } else {
11332                    name = args[opti];
11333                    opti++;
11334                    newArgs = new String[args.length - opti];
11335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11336                            args.length - opti);
11337                }
11338                synchronized (this) {
11339                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11340                }
11341            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11342                synchronized (this) {
11343                    dumpOomLocked(fd, pw, args, opti, true);
11344                }
11345            } else if ("provider".equals(cmd)) {
11346                String[] newArgs;
11347                String name;
11348                if (opti >= args.length) {
11349                    name = null;
11350                    newArgs = EMPTY_STRING_ARRAY;
11351                } else {
11352                    name = args[opti];
11353                    opti++;
11354                    newArgs = new String[args.length - opti];
11355                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11356                }
11357                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11358                    pw.println("No providers match: " + name);
11359                    pw.println("Use -h for help.");
11360                }
11361            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11362                synchronized (this) {
11363                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11364                }
11365            } else if ("service".equals(cmd)) {
11366                String[] newArgs;
11367                String name;
11368                if (opti >= args.length) {
11369                    name = null;
11370                    newArgs = EMPTY_STRING_ARRAY;
11371                } else {
11372                    name = args[opti];
11373                    opti++;
11374                    newArgs = new String[args.length - opti];
11375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11376                            args.length - opti);
11377                }
11378                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11379                    pw.println("No services match: " + name);
11380                    pw.println("Use -h for help.");
11381                }
11382            } else if ("package".equals(cmd)) {
11383                String[] newArgs;
11384                if (opti >= args.length) {
11385                    pw.println("package: no package name specified");
11386                    pw.println("Use -h for help.");
11387                } else {
11388                    dumpPackage = args[opti];
11389                    opti++;
11390                    newArgs = new String[args.length - opti];
11391                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11392                            args.length - opti);
11393                    args = newArgs;
11394                    opti = 0;
11395                    more = true;
11396                }
11397            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11398                synchronized (this) {
11399                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11400                }
11401            } else {
11402                // Dumping a single activity?
11403                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11404                    pw.println("Bad activity command, or no activities match: " + cmd);
11405                    pw.println("Use -h for help.");
11406                }
11407            }
11408            if (!more) {
11409                Binder.restoreCallingIdentity(origId);
11410                return;
11411            }
11412        }
11413
11414        // No piece of data specified, dump everything.
11415        synchronized (this) {
11416            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11417            pw.println();
11418            if (dumpAll) {
11419                pw.println("-------------------------------------------------------------------------------");
11420            }
11421            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11422            pw.println();
11423            if (dumpAll) {
11424                pw.println("-------------------------------------------------------------------------------");
11425            }
11426            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11427            pw.println();
11428            if (dumpAll) {
11429                pw.println("-------------------------------------------------------------------------------");
11430            }
11431            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11432            pw.println();
11433            if (dumpAll) {
11434                pw.println("-------------------------------------------------------------------------------");
11435            }
11436            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11437            pw.println();
11438            if (dumpAll) {
11439                pw.println("-------------------------------------------------------------------------------");
11440            }
11441            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11442        }
11443        Binder.restoreCallingIdentity(origId);
11444    }
11445
11446    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11447            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11448        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11449
11450        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11451                dumpPackage);
11452        boolean needSep = printedAnything;
11453
11454        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11455                dumpPackage, needSep, "  mFocusedActivity: ");
11456        if (printed) {
11457            printedAnything = true;
11458            needSep = false;
11459        }
11460
11461        if (dumpPackage == null) {
11462            if (needSep) {
11463                pw.println();
11464            }
11465            needSep = true;
11466            printedAnything = true;
11467            mStackSupervisor.dump(pw, "  ");
11468        }
11469
11470        if (mRecentTasks.size() > 0) {
11471            boolean printedHeader = false;
11472
11473            final int N = mRecentTasks.size();
11474            for (int i=0; i<N; i++) {
11475                TaskRecord tr = mRecentTasks.get(i);
11476                if (dumpPackage != null) {
11477                    if (tr.realActivity == null ||
11478                            !dumpPackage.equals(tr.realActivity)) {
11479                        continue;
11480                    }
11481                }
11482                if (!printedHeader) {
11483                    if (needSep) {
11484                        pw.println();
11485                    }
11486                    pw.println("  Recent tasks:");
11487                    printedHeader = true;
11488                    printedAnything = true;
11489                }
11490                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11491                        pw.println(tr);
11492                if (dumpAll) {
11493                    mRecentTasks.get(i).dump(pw, "    ");
11494                }
11495            }
11496        }
11497
11498        if (!printedAnything) {
11499            pw.println("  (nothing)");
11500        }
11501    }
11502
11503    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11504            int opti, boolean dumpAll, String dumpPackage) {
11505        boolean needSep = false;
11506        boolean printedAnything = false;
11507        int numPers = 0;
11508
11509        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11510
11511        if (dumpAll) {
11512            final int NP = mProcessNames.getMap().size();
11513            for (int ip=0; ip<NP; ip++) {
11514                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11515                final int NA = procs.size();
11516                for (int ia=0; ia<NA; ia++) {
11517                    ProcessRecord r = procs.valueAt(ia);
11518                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11519                        continue;
11520                    }
11521                    if (!needSep) {
11522                        pw.println("  All known processes:");
11523                        needSep = true;
11524                        printedAnything = true;
11525                    }
11526                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11527                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11528                        pw.print(" "); pw.println(r);
11529                    r.dump(pw, "    ");
11530                    if (r.persistent) {
11531                        numPers++;
11532                    }
11533                }
11534            }
11535        }
11536
11537        if (mIsolatedProcesses.size() > 0) {
11538            boolean printed = false;
11539            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11540                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11541                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11542                    continue;
11543                }
11544                if (!printed) {
11545                    if (needSep) {
11546                        pw.println();
11547                    }
11548                    pw.println("  Isolated process list (sorted by uid):");
11549                    printedAnything = true;
11550                    printed = true;
11551                    needSep = true;
11552                }
11553                pw.println(String.format("%sIsolated #%2d: %s",
11554                        "    ", i, r.toString()));
11555            }
11556        }
11557
11558        if (mLruProcesses.size() > 0) {
11559            if (needSep) {
11560                pw.println();
11561            }
11562            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11563                    pw.print(" total, non-act at ");
11564                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11565                    pw.print(", non-svc at ");
11566                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11567                    pw.println("):");
11568            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11569            needSep = true;
11570            printedAnything = true;
11571        }
11572
11573        if (dumpAll || dumpPackage != null) {
11574            synchronized (mPidsSelfLocked) {
11575                boolean printed = false;
11576                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11577                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11578                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11579                        continue;
11580                    }
11581                    if (!printed) {
11582                        if (needSep) pw.println();
11583                        needSep = true;
11584                        pw.println("  PID mappings:");
11585                        printed = true;
11586                        printedAnything = true;
11587                    }
11588                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11589                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11590                }
11591            }
11592        }
11593
11594        if (mForegroundProcesses.size() > 0) {
11595            synchronized (mPidsSelfLocked) {
11596                boolean printed = false;
11597                for (int i=0; i<mForegroundProcesses.size(); i++) {
11598                    ProcessRecord r = mPidsSelfLocked.get(
11599                            mForegroundProcesses.valueAt(i).pid);
11600                    if (dumpPackage != null && (r == null
11601                            || !r.pkgList.containsKey(dumpPackage))) {
11602                        continue;
11603                    }
11604                    if (!printed) {
11605                        if (needSep) pw.println();
11606                        needSep = true;
11607                        pw.println("  Foreground Processes:");
11608                        printed = true;
11609                        printedAnything = true;
11610                    }
11611                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11612                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11613                }
11614            }
11615        }
11616
11617        if (mPersistentStartingProcesses.size() > 0) {
11618            if (needSep) pw.println();
11619            needSep = true;
11620            printedAnything = true;
11621            pw.println("  Persisent processes that are starting:");
11622            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11623                    "Starting Norm", "Restarting PERS", dumpPackage);
11624        }
11625
11626        if (mRemovedProcesses.size() > 0) {
11627            if (needSep) pw.println();
11628            needSep = true;
11629            printedAnything = true;
11630            pw.println("  Processes that are being removed:");
11631            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11632                    "Removed Norm", "Removed PERS", dumpPackage);
11633        }
11634
11635        if (mProcessesOnHold.size() > 0) {
11636            if (needSep) pw.println();
11637            needSep = true;
11638            printedAnything = true;
11639            pw.println("  Processes that are on old until the system is ready:");
11640            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11641                    "OnHold Norm", "OnHold PERS", dumpPackage);
11642        }
11643
11644        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11645
11646        if (mProcessCrashTimes.getMap().size() > 0) {
11647            boolean printed = false;
11648            long now = SystemClock.uptimeMillis();
11649            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11650            final int NP = pmap.size();
11651            for (int ip=0; ip<NP; ip++) {
11652                String pname = pmap.keyAt(ip);
11653                SparseArray<Long> uids = pmap.valueAt(ip);
11654                final int N = uids.size();
11655                for (int i=0; i<N; i++) {
11656                    int puid = uids.keyAt(i);
11657                    ProcessRecord r = mProcessNames.get(pname, puid);
11658                    if (dumpPackage != null && (r == null
11659                            || !r.pkgList.containsKey(dumpPackage))) {
11660                        continue;
11661                    }
11662                    if (!printed) {
11663                        if (needSep) pw.println();
11664                        needSep = true;
11665                        pw.println("  Time since processes crashed:");
11666                        printed = true;
11667                        printedAnything = true;
11668                    }
11669                    pw.print("    Process "); pw.print(pname);
11670                            pw.print(" uid "); pw.print(puid);
11671                            pw.print(": last crashed ");
11672                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11673                            pw.println(" ago");
11674                }
11675            }
11676        }
11677
11678        if (mBadProcesses.getMap().size() > 0) {
11679            boolean printed = false;
11680            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11681            final int NP = pmap.size();
11682            for (int ip=0; ip<NP; ip++) {
11683                String pname = pmap.keyAt(ip);
11684                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11685                final int N = uids.size();
11686                for (int i=0; i<N; i++) {
11687                    int puid = uids.keyAt(i);
11688                    ProcessRecord r = mProcessNames.get(pname, puid);
11689                    if (dumpPackage != null && (r == null
11690                            || !r.pkgList.containsKey(dumpPackage))) {
11691                        continue;
11692                    }
11693                    if (!printed) {
11694                        if (needSep) pw.println();
11695                        needSep = true;
11696                        pw.println("  Bad processes:");
11697                        printedAnything = true;
11698                    }
11699                    BadProcessInfo info = uids.valueAt(i);
11700                    pw.print("    Bad process "); pw.print(pname);
11701                            pw.print(" uid "); pw.print(puid);
11702                            pw.print(": crashed at time "); pw.println(info.time);
11703                    if (info.shortMsg != null) {
11704                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11705                    }
11706                    if (info.longMsg != null) {
11707                        pw.print("      Long msg: "); pw.println(info.longMsg);
11708                    }
11709                    if (info.stack != null) {
11710                        pw.println("      Stack:");
11711                        int lastPos = 0;
11712                        for (int pos=0; pos<info.stack.length(); pos++) {
11713                            if (info.stack.charAt(pos) == '\n') {
11714                                pw.print("        ");
11715                                pw.write(info.stack, lastPos, pos-lastPos);
11716                                pw.println();
11717                                lastPos = pos+1;
11718                            }
11719                        }
11720                        if (lastPos < info.stack.length()) {
11721                            pw.print("        ");
11722                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11723                            pw.println();
11724                        }
11725                    }
11726                }
11727            }
11728        }
11729
11730        if (dumpPackage == null) {
11731            pw.println();
11732            needSep = false;
11733            pw.println("  mStartedUsers:");
11734            for (int i=0; i<mStartedUsers.size(); i++) {
11735                UserStartedState uss = mStartedUsers.valueAt(i);
11736                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11737                        pw.print(": "); uss.dump("", pw);
11738            }
11739            pw.print("  mStartedUserArray: [");
11740            for (int i=0; i<mStartedUserArray.length; i++) {
11741                if (i > 0) pw.print(", ");
11742                pw.print(mStartedUserArray[i]);
11743            }
11744            pw.println("]");
11745            pw.print("  mUserLru: [");
11746            for (int i=0; i<mUserLru.size(); i++) {
11747                if (i > 0) pw.print(", ");
11748                pw.print(mUserLru.get(i));
11749            }
11750            pw.println("]");
11751            if (dumpAll) {
11752                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11753            }
11754            synchronized (mUserProfileGroupIdsSelfLocked) {
11755                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11756                    pw.println("  mUserProfileGroupIds:");
11757                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11758                        pw.print("    User #");
11759                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11760                        pw.print(" -> profile #");
11761                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11762                    }
11763                }
11764            }
11765        }
11766        if (mHomeProcess != null && (dumpPackage == null
11767                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11768            if (needSep) {
11769                pw.println();
11770                needSep = false;
11771            }
11772            pw.println("  mHomeProcess: " + mHomeProcess);
11773        }
11774        if (mPreviousProcess != null && (dumpPackage == null
11775                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11776            if (needSep) {
11777                pw.println();
11778                needSep = false;
11779            }
11780            pw.println("  mPreviousProcess: " + mPreviousProcess);
11781        }
11782        if (dumpAll) {
11783            StringBuilder sb = new StringBuilder(128);
11784            sb.append("  mPreviousProcessVisibleTime: ");
11785            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11786            pw.println(sb);
11787        }
11788        if (mHeavyWeightProcess != null && (dumpPackage == null
11789                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11790            if (needSep) {
11791                pw.println();
11792                needSep = false;
11793            }
11794            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11795        }
11796        if (dumpPackage == null) {
11797            pw.println("  mConfiguration: " + mConfiguration);
11798        }
11799        if (dumpAll) {
11800            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11801            if (mCompatModePackages.getPackages().size() > 0) {
11802                boolean printed = false;
11803                for (Map.Entry<String, Integer> entry
11804                        : mCompatModePackages.getPackages().entrySet()) {
11805                    String pkg = entry.getKey();
11806                    int mode = entry.getValue();
11807                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11808                        continue;
11809                    }
11810                    if (!printed) {
11811                        pw.println("  mScreenCompatPackages:");
11812                        printed = true;
11813                    }
11814                    pw.print("    "); pw.print(pkg); pw.print(": ");
11815                            pw.print(mode); pw.println();
11816                }
11817            }
11818        }
11819        if (dumpPackage == null) {
11820            if (mSleeping || mWentToSleep || mLockScreenShown) {
11821                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11822                        + " mLockScreenShown " + mLockScreenShown);
11823            }
11824            if (mShuttingDown || mRunningVoice) {
11825                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11826            }
11827        }
11828        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11829                || mOrigWaitForDebugger) {
11830            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11831                    || dumpPackage.equals(mOrigDebugApp)) {
11832                if (needSep) {
11833                    pw.println();
11834                    needSep = false;
11835                }
11836                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11837                        + " mDebugTransient=" + mDebugTransient
11838                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11839            }
11840        }
11841        if (mOpenGlTraceApp != null) {
11842            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11843                if (needSep) {
11844                    pw.println();
11845                    needSep = false;
11846                }
11847                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11848            }
11849        }
11850        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11851                || mProfileFd != null) {
11852            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11853                if (needSep) {
11854                    pw.println();
11855                    needSep = false;
11856                }
11857                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11858                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11859                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11860                        + mAutoStopProfiler);
11861            }
11862        }
11863        if (dumpPackage == null) {
11864            if (mAlwaysFinishActivities || mController != null) {
11865                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11866                        + " mController=" + mController);
11867            }
11868            if (dumpAll) {
11869                pw.println("  Total persistent processes: " + numPers);
11870                pw.println("  mProcessesReady=" + mProcessesReady
11871                        + " mSystemReady=" + mSystemReady);
11872                pw.println("  mBooting=" + mBooting
11873                        + " mBooted=" + mBooted
11874                        + " mFactoryTest=" + mFactoryTest);
11875                pw.print("  mLastPowerCheckRealtime=");
11876                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11877                        pw.println("");
11878                pw.print("  mLastPowerCheckUptime=");
11879                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11880                        pw.println("");
11881                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11882                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11883                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11884                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11885                        + " (" + mLruProcesses.size() + " total)"
11886                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11887                        + " mNumServiceProcs=" + mNumServiceProcs
11888                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11889                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11890                        + " mLastMemoryLevel" + mLastMemoryLevel
11891                        + " mLastNumProcesses" + mLastNumProcesses);
11892                long now = SystemClock.uptimeMillis();
11893                pw.print("  mLastIdleTime=");
11894                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11895                        pw.print(" mLowRamSinceLastIdle=");
11896                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11897                        pw.println();
11898            }
11899        }
11900
11901        if (!printedAnything) {
11902            pw.println("  (nothing)");
11903        }
11904    }
11905
11906    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11907            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11908        if (mProcessesToGc.size() > 0) {
11909            boolean printed = false;
11910            long now = SystemClock.uptimeMillis();
11911            for (int i=0; i<mProcessesToGc.size(); i++) {
11912                ProcessRecord proc = mProcessesToGc.get(i);
11913                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11914                    continue;
11915                }
11916                if (!printed) {
11917                    if (needSep) pw.println();
11918                    needSep = true;
11919                    pw.println("  Processes that are waiting to GC:");
11920                    printed = true;
11921                }
11922                pw.print("    Process "); pw.println(proc);
11923                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11924                        pw.print(", last gced=");
11925                        pw.print(now-proc.lastRequestedGc);
11926                        pw.print(" ms ago, last lowMem=");
11927                        pw.print(now-proc.lastLowMemory);
11928                        pw.println(" ms ago");
11929
11930            }
11931        }
11932        return needSep;
11933    }
11934
11935    void printOomLevel(PrintWriter pw, String name, int adj) {
11936        pw.print("    ");
11937        if (adj >= 0) {
11938            pw.print(' ');
11939            if (adj < 10) pw.print(' ');
11940        } else {
11941            if (adj > -10) pw.print(' ');
11942        }
11943        pw.print(adj);
11944        pw.print(": ");
11945        pw.print(name);
11946        pw.print(" (");
11947        pw.print(mProcessList.getMemLevel(adj)/1024);
11948        pw.println(" kB)");
11949    }
11950
11951    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11952            int opti, boolean dumpAll) {
11953        boolean needSep = false;
11954
11955        if (mLruProcesses.size() > 0) {
11956            if (needSep) pw.println();
11957            needSep = true;
11958            pw.println("  OOM levels:");
11959            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11960            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11961            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11962            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11963            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11964            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11965            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11966            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11967            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11968            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11969            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11970            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11971            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11972
11973            if (needSep) pw.println();
11974            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11975                    pw.print(" total, non-act at ");
11976                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11977                    pw.print(", non-svc at ");
11978                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11979                    pw.println("):");
11980            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11981            needSep = true;
11982        }
11983
11984        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11985
11986        pw.println();
11987        pw.println("  mHomeProcess: " + mHomeProcess);
11988        pw.println("  mPreviousProcess: " + mPreviousProcess);
11989        if (mHeavyWeightProcess != null) {
11990            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11991        }
11992
11993        return true;
11994    }
11995
11996    /**
11997     * There are three ways to call this:
11998     *  - no provider specified: dump all the providers
11999     *  - a flattened component name that matched an existing provider was specified as the
12000     *    first arg: dump that one provider
12001     *  - the first arg isn't the flattened component name of an existing provider:
12002     *    dump all providers whose component contains the first arg as a substring
12003     */
12004    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12005            int opti, boolean dumpAll) {
12006        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12007    }
12008
12009    static class ItemMatcher {
12010        ArrayList<ComponentName> components;
12011        ArrayList<String> strings;
12012        ArrayList<Integer> objects;
12013        boolean all;
12014
12015        ItemMatcher() {
12016            all = true;
12017        }
12018
12019        void build(String name) {
12020            ComponentName componentName = ComponentName.unflattenFromString(name);
12021            if (componentName != null) {
12022                if (components == null) {
12023                    components = new ArrayList<ComponentName>();
12024                }
12025                components.add(componentName);
12026                all = false;
12027            } else {
12028                int objectId = 0;
12029                // Not a '/' separated full component name; maybe an object ID?
12030                try {
12031                    objectId = Integer.parseInt(name, 16);
12032                    if (objects == null) {
12033                        objects = new ArrayList<Integer>();
12034                    }
12035                    objects.add(objectId);
12036                    all = false;
12037                } catch (RuntimeException e) {
12038                    // Not an integer; just do string match.
12039                    if (strings == null) {
12040                        strings = new ArrayList<String>();
12041                    }
12042                    strings.add(name);
12043                    all = false;
12044                }
12045            }
12046        }
12047
12048        int build(String[] args, int opti) {
12049            for (; opti<args.length; opti++) {
12050                String name = args[opti];
12051                if ("--".equals(name)) {
12052                    return opti+1;
12053                }
12054                build(name);
12055            }
12056            return opti;
12057        }
12058
12059        boolean match(Object object, ComponentName comp) {
12060            if (all) {
12061                return true;
12062            }
12063            if (components != null) {
12064                for (int i=0; i<components.size(); i++) {
12065                    if (components.get(i).equals(comp)) {
12066                        return true;
12067                    }
12068                }
12069            }
12070            if (objects != null) {
12071                for (int i=0; i<objects.size(); i++) {
12072                    if (System.identityHashCode(object) == objects.get(i)) {
12073                        return true;
12074                    }
12075                }
12076            }
12077            if (strings != null) {
12078                String flat = comp.flattenToString();
12079                for (int i=0; i<strings.size(); i++) {
12080                    if (flat.contains(strings.get(i))) {
12081                        return true;
12082                    }
12083                }
12084            }
12085            return false;
12086        }
12087    }
12088
12089    /**
12090     * There are three things that cmd can be:
12091     *  - a flattened component name that matches an existing activity
12092     *  - the cmd arg isn't the flattened component name of an existing activity:
12093     *    dump all activity whose component contains the cmd as a substring
12094     *  - A hex number of the ActivityRecord object instance.
12095     */
12096    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12097            int opti, boolean dumpAll) {
12098        ArrayList<ActivityRecord> activities;
12099
12100        synchronized (this) {
12101            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12102        }
12103
12104        if (activities.size() <= 0) {
12105            return false;
12106        }
12107
12108        String[] newArgs = new String[args.length - opti];
12109        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12110
12111        TaskRecord lastTask = null;
12112        boolean needSep = false;
12113        for (int i=activities.size()-1; i>=0; i--) {
12114            ActivityRecord r = activities.get(i);
12115            if (needSep) {
12116                pw.println();
12117            }
12118            needSep = true;
12119            synchronized (this) {
12120                if (lastTask != r.task) {
12121                    lastTask = r.task;
12122                    pw.print("TASK "); pw.print(lastTask.affinity);
12123                            pw.print(" id="); pw.println(lastTask.taskId);
12124                    if (dumpAll) {
12125                        lastTask.dump(pw, "  ");
12126                    }
12127                }
12128            }
12129            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12130        }
12131        return true;
12132    }
12133
12134    /**
12135     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12136     * there is a thread associated with the activity.
12137     */
12138    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12139            final ActivityRecord r, String[] args, boolean dumpAll) {
12140        String innerPrefix = prefix + "  ";
12141        synchronized (this) {
12142            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12143                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12144                    pw.print(" pid=");
12145                    if (r.app != null) pw.println(r.app.pid);
12146                    else pw.println("(not running)");
12147            if (dumpAll) {
12148                r.dump(pw, innerPrefix);
12149            }
12150        }
12151        if (r.app != null && r.app.thread != null) {
12152            // flush anything that is already in the PrintWriter since the thread is going
12153            // to write to the file descriptor directly
12154            pw.flush();
12155            try {
12156                TransferPipe tp = new TransferPipe();
12157                try {
12158                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12159                            r.appToken, innerPrefix, args);
12160                    tp.go(fd);
12161                } finally {
12162                    tp.kill();
12163                }
12164            } catch (IOException e) {
12165                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12166            } catch (RemoteException e) {
12167                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12168            }
12169        }
12170    }
12171
12172    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12173            int opti, boolean dumpAll, String dumpPackage) {
12174        boolean needSep = false;
12175        boolean onlyHistory = false;
12176        boolean printedAnything = false;
12177
12178        if ("history".equals(dumpPackage)) {
12179            if (opti < args.length && "-s".equals(args[opti])) {
12180                dumpAll = false;
12181            }
12182            onlyHistory = true;
12183            dumpPackage = null;
12184        }
12185
12186        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12187        if (!onlyHistory && dumpAll) {
12188            if (mRegisteredReceivers.size() > 0) {
12189                boolean printed = false;
12190                Iterator it = mRegisteredReceivers.values().iterator();
12191                while (it.hasNext()) {
12192                    ReceiverList r = (ReceiverList)it.next();
12193                    if (dumpPackage != null && (r.app == null ||
12194                            !dumpPackage.equals(r.app.info.packageName))) {
12195                        continue;
12196                    }
12197                    if (!printed) {
12198                        pw.println("  Registered Receivers:");
12199                        needSep = true;
12200                        printed = true;
12201                        printedAnything = true;
12202                    }
12203                    pw.print("  * "); pw.println(r);
12204                    r.dump(pw, "    ");
12205                }
12206            }
12207
12208            if (mReceiverResolver.dump(pw, needSep ?
12209                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12210                    "    ", dumpPackage, false)) {
12211                needSep = true;
12212                printedAnything = true;
12213            }
12214        }
12215
12216        for (BroadcastQueue q : mBroadcastQueues) {
12217            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12218            printedAnything |= needSep;
12219        }
12220
12221        needSep = true;
12222
12223        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12224            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12225                if (needSep) {
12226                    pw.println();
12227                }
12228                needSep = true;
12229                printedAnything = true;
12230                pw.print("  Sticky broadcasts for user ");
12231                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12232                StringBuilder sb = new StringBuilder(128);
12233                for (Map.Entry<String, ArrayList<Intent>> ent
12234                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12235                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12236                    if (dumpAll) {
12237                        pw.println(":");
12238                        ArrayList<Intent> intents = ent.getValue();
12239                        final int N = intents.size();
12240                        for (int i=0; i<N; i++) {
12241                            sb.setLength(0);
12242                            sb.append("    Intent: ");
12243                            intents.get(i).toShortString(sb, false, true, false, false);
12244                            pw.println(sb.toString());
12245                            Bundle bundle = intents.get(i).getExtras();
12246                            if (bundle != null) {
12247                                pw.print("      ");
12248                                pw.println(bundle.toString());
12249                            }
12250                        }
12251                    } else {
12252                        pw.println("");
12253                    }
12254                }
12255            }
12256        }
12257
12258        if (!onlyHistory && dumpAll) {
12259            pw.println();
12260            for (BroadcastQueue queue : mBroadcastQueues) {
12261                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12262                        + queue.mBroadcastsScheduled);
12263            }
12264            pw.println("  mHandler:");
12265            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12266            needSep = true;
12267            printedAnything = true;
12268        }
12269
12270        if (!printedAnything) {
12271            pw.println("  (nothing)");
12272        }
12273    }
12274
12275    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12276            int opti, boolean dumpAll, String dumpPackage) {
12277        boolean needSep;
12278        boolean printedAnything = false;
12279
12280        ItemMatcher matcher = new ItemMatcher();
12281        matcher.build(args, opti);
12282
12283        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12284
12285        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12286        printedAnything |= needSep;
12287
12288        if (mLaunchingProviders.size() > 0) {
12289            boolean printed = false;
12290            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12291                ContentProviderRecord r = mLaunchingProviders.get(i);
12292                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12293                    continue;
12294                }
12295                if (!printed) {
12296                    if (needSep) pw.println();
12297                    needSep = true;
12298                    pw.println("  Launching content providers:");
12299                    printed = true;
12300                    printedAnything = true;
12301                }
12302                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12303                        pw.println(r);
12304            }
12305        }
12306
12307        if (mGrantedUriPermissions.size() > 0) {
12308            boolean printed = false;
12309            int dumpUid = -2;
12310            if (dumpPackage != null) {
12311                try {
12312                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12313                } catch (NameNotFoundException e) {
12314                    dumpUid = -1;
12315                }
12316            }
12317            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12318                int uid = mGrantedUriPermissions.keyAt(i);
12319                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12320                    continue;
12321                }
12322                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12323                if (!printed) {
12324                    if (needSep) pw.println();
12325                    needSep = true;
12326                    pw.println("  Granted Uri Permissions:");
12327                    printed = true;
12328                    printedAnything = true;
12329                }
12330                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12331                for (UriPermission perm : perms.values()) {
12332                    pw.print("    "); pw.println(perm);
12333                    if (dumpAll) {
12334                        perm.dump(pw, "      ");
12335                    }
12336                }
12337            }
12338        }
12339
12340        if (!printedAnything) {
12341            pw.println("  (nothing)");
12342        }
12343    }
12344
12345    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12346            int opti, boolean dumpAll, String dumpPackage) {
12347        boolean printed = false;
12348
12349        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12350
12351        if (mIntentSenderRecords.size() > 0) {
12352            Iterator<WeakReference<PendingIntentRecord>> it
12353                    = mIntentSenderRecords.values().iterator();
12354            while (it.hasNext()) {
12355                WeakReference<PendingIntentRecord> ref = it.next();
12356                PendingIntentRecord rec = ref != null ? ref.get(): null;
12357                if (dumpPackage != null && (rec == null
12358                        || !dumpPackage.equals(rec.key.packageName))) {
12359                    continue;
12360                }
12361                printed = true;
12362                if (rec != null) {
12363                    pw.print("  * "); pw.println(rec);
12364                    if (dumpAll) {
12365                        rec.dump(pw, "    ");
12366                    }
12367                } else {
12368                    pw.print("  * "); pw.println(ref);
12369                }
12370            }
12371        }
12372
12373        if (!printed) {
12374            pw.println("  (nothing)");
12375        }
12376    }
12377
12378    private static final int dumpProcessList(PrintWriter pw,
12379            ActivityManagerService service, List list,
12380            String prefix, String normalLabel, String persistentLabel,
12381            String dumpPackage) {
12382        int numPers = 0;
12383        final int N = list.size()-1;
12384        for (int i=N; i>=0; i--) {
12385            ProcessRecord r = (ProcessRecord)list.get(i);
12386            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12387                continue;
12388            }
12389            pw.println(String.format("%s%s #%2d: %s",
12390                    prefix, (r.persistent ? persistentLabel : normalLabel),
12391                    i, r.toString()));
12392            if (r.persistent) {
12393                numPers++;
12394            }
12395        }
12396        return numPers;
12397    }
12398
12399    private static final boolean dumpProcessOomList(PrintWriter pw,
12400            ActivityManagerService service, List<ProcessRecord> origList,
12401            String prefix, String normalLabel, String persistentLabel,
12402            boolean inclDetails, String dumpPackage) {
12403
12404        ArrayList<Pair<ProcessRecord, Integer>> list
12405                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12406        for (int i=0; i<origList.size(); i++) {
12407            ProcessRecord r = origList.get(i);
12408            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12409                continue;
12410            }
12411            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12412        }
12413
12414        if (list.size() <= 0) {
12415            return false;
12416        }
12417
12418        Comparator<Pair<ProcessRecord, Integer>> comparator
12419                = new Comparator<Pair<ProcessRecord, Integer>>() {
12420            @Override
12421            public int compare(Pair<ProcessRecord, Integer> object1,
12422                    Pair<ProcessRecord, Integer> object2) {
12423                if (object1.first.setAdj != object2.first.setAdj) {
12424                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12425                }
12426                if (object1.second.intValue() != object2.second.intValue()) {
12427                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12428                }
12429                return 0;
12430            }
12431        };
12432
12433        Collections.sort(list, comparator);
12434
12435        final long curRealtime = SystemClock.elapsedRealtime();
12436        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12437        final long curUptime = SystemClock.uptimeMillis();
12438        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12439
12440        for (int i=list.size()-1; i>=0; i--) {
12441            ProcessRecord r = list.get(i).first;
12442            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12443            char schedGroup;
12444            switch (r.setSchedGroup) {
12445                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12446                    schedGroup = 'B';
12447                    break;
12448                case Process.THREAD_GROUP_DEFAULT:
12449                    schedGroup = 'F';
12450                    break;
12451                default:
12452                    schedGroup = '?';
12453                    break;
12454            }
12455            char foreground;
12456            if (r.foregroundActivities) {
12457                foreground = 'A';
12458            } else if (r.foregroundServices) {
12459                foreground = 'S';
12460            } else {
12461                foreground = ' ';
12462            }
12463            String procState = ProcessList.makeProcStateString(r.curProcState);
12464            pw.print(prefix);
12465            pw.print(r.persistent ? persistentLabel : normalLabel);
12466            pw.print(" #");
12467            int num = (origList.size()-1)-list.get(i).second;
12468            if (num < 10) pw.print(' ');
12469            pw.print(num);
12470            pw.print(": ");
12471            pw.print(oomAdj);
12472            pw.print(' ');
12473            pw.print(schedGroup);
12474            pw.print('/');
12475            pw.print(foreground);
12476            pw.print('/');
12477            pw.print(procState);
12478            pw.print(" trm:");
12479            if (r.trimMemoryLevel < 10) pw.print(' ');
12480            pw.print(r.trimMemoryLevel);
12481            pw.print(' ');
12482            pw.print(r.toShortString());
12483            pw.print(" (");
12484            pw.print(r.adjType);
12485            pw.println(')');
12486            if (r.adjSource != null || r.adjTarget != null) {
12487                pw.print(prefix);
12488                pw.print("    ");
12489                if (r.adjTarget instanceof ComponentName) {
12490                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12491                } else if (r.adjTarget != null) {
12492                    pw.print(r.adjTarget.toString());
12493                } else {
12494                    pw.print("{null}");
12495                }
12496                pw.print("<=");
12497                if (r.adjSource instanceof ProcessRecord) {
12498                    pw.print("Proc{");
12499                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12500                    pw.println("}");
12501                } else if (r.adjSource != null) {
12502                    pw.println(r.adjSource.toString());
12503                } else {
12504                    pw.println("{null}");
12505                }
12506            }
12507            if (inclDetails) {
12508                pw.print(prefix);
12509                pw.print("    ");
12510                pw.print("oom: max="); pw.print(r.maxAdj);
12511                pw.print(" curRaw="); pw.print(r.curRawAdj);
12512                pw.print(" setRaw="); pw.print(r.setRawAdj);
12513                pw.print(" cur="); pw.print(r.curAdj);
12514                pw.print(" set="); pw.println(r.setAdj);
12515                pw.print(prefix);
12516                pw.print("    ");
12517                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12518                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12519                pw.print(" lastPss="); pw.print(r.lastPss);
12520                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12521                pw.print(prefix);
12522                pw.print("    ");
12523                pw.print("cached="); pw.print(r.cached);
12524                pw.print(" empty="); pw.print(r.empty);
12525                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12526
12527                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12528                    if (r.lastWakeTime != 0) {
12529                        long wtime;
12530                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12531                        synchronized (stats) {
12532                            wtime = stats.getProcessWakeTime(r.info.uid,
12533                                    r.pid, curRealtime);
12534                        }
12535                        long timeUsed = wtime - r.lastWakeTime;
12536                        pw.print(prefix);
12537                        pw.print("    ");
12538                        pw.print("keep awake over ");
12539                        TimeUtils.formatDuration(realtimeSince, pw);
12540                        pw.print(" used ");
12541                        TimeUtils.formatDuration(timeUsed, pw);
12542                        pw.print(" (");
12543                        pw.print((timeUsed*100)/realtimeSince);
12544                        pw.println("%)");
12545                    }
12546                    if (r.lastCpuTime != 0) {
12547                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12548                        pw.print(prefix);
12549                        pw.print("    ");
12550                        pw.print("run cpu over ");
12551                        TimeUtils.formatDuration(uptimeSince, pw);
12552                        pw.print(" used ");
12553                        TimeUtils.formatDuration(timeUsed, pw);
12554                        pw.print(" (");
12555                        pw.print((timeUsed*100)/uptimeSince);
12556                        pw.println("%)");
12557                    }
12558                }
12559            }
12560        }
12561        return true;
12562    }
12563
12564    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12565        ArrayList<ProcessRecord> procs;
12566        synchronized (this) {
12567            if (args != null && args.length > start
12568                    && args[start].charAt(0) != '-') {
12569                procs = new ArrayList<ProcessRecord>();
12570                int pid = -1;
12571                try {
12572                    pid = Integer.parseInt(args[start]);
12573                } catch (NumberFormatException e) {
12574                }
12575                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12576                    ProcessRecord proc = mLruProcesses.get(i);
12577                    if (proc.pid == pid) {
12578                        procs.add(proc);
12579                    } else if (proc.processName.equals(args[start])) {
12580                        procs.add(proc);
12581                    }
12582                }
12583                if (procs.size() <= 0) {
12584                    return null;
12585                }
12586            } else {
12587                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12588            }
12589        }
12590        return procs;
12591    }
12592
12593    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12594            PrintWriter pw, String[] args) {
12595        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12596        if (procs == null) {
12597            pw.println("No process found for: " + args[0]);
12598            return;
12599        }
12600
12601        long uptime = SystemClock.uptimeMillis();
12602        long realtime = SystemClock.elapsedRealtime();
12603        pw.println("Applications Graphics Acceleration Info:");
12604        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12605
12606        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12607            ProcessRecord r = procs.get(i);
12608            if (r.thread != null) {
12609                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12610                pw.flush();
12611                try {
12612                    TransferPipe tp = new TransferPipe();
12613                    try {
12614                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12615                        tp.go(fd);
12616                    } finally {
12617                        tp.kill();
12618                    }
12619                } catch (IOException e) {
12620                    pw.println("Failure while dumping the app: " + r);
12621                    pw.flush();
12622                } catch (RemoteException e) {
12623                    pw.println("Got a RemoteException while dumping the app " + r);
12624                    pw.flush();
12625                }
12626            }
12627        }
12628    }
12629
12630    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12631        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12632        if (procs == null) {
12633            pw.println("No process found for: " + args[0]);
12634            return;
12635        }
12636
12637        pw.println("Applications Database Info:");
12638
12639        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12640            ProcessRecord r = procs.get(i);
12641            if (r.thread != null) {
12642                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12643                pw.flush();
12644                try {
12645                    TransferPipe tp = new TransferPipe();
12646                    try {
12647                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12648                        tp.go(fd);
12649                    } finally {
12650                        tp.kill();
12651                    }
12652                } catch (IOException e) {
12653                    pw.println("Failure while dumping the app: " + r);
12654                    pw.flush();
12655                } catch (RemoteException e) {
12656                    pw.println("Got a RemoteException while dumping the app " + r);
12657                    pw.flush();
12658                }
12659            }
12660        }
12661    }
12662
12663    final static class MemItem {
12664        final boolean isProc;
12665        final String label;
12666        final String shortLabel;
12667        final long pss;
12668        final int id;
12669        final boolean hasActivities;
12670        ArrayList<MemItem> subitems;
12671
12672        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12673                boolean _hasActivities) {
12674            isProc = true;
12675            label = _label;
12676            shortLabel = _shortLabel;
12677            pss = _pss;
12678            id = _id;
12679            hasActivities = _hasActivities;
12680        }
12681
12682        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12683            isProc = false;
12684            label = _label;
12685            shortLabel = _shortLabel;
12686            pss = _pss;
12687            id = _id;
12688            hasActivities = false;
12689        }
12690    }
12691
12692    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12693            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12694        if (sort && !isCompact) {
12695            Collections.sort(items, new Comparator<MemItem>() {
12696                @Override
12697                public int compare(MemItem lhs, MemItem rhs) {
12698                    if (lhs.pss < rhs.pss) {
12699                        return 1;
12700                    } else if (lhs.pss > rhs.pss) {
12701                        return -1;
12702                    }
12703                    return 0;
12704                }
12705            });
12706        }
12707
12708        for (int i=0; i<items.size(); i++) {
12709            MemItem mi = items.get(i);
12710            if (!isCompact) {
12711                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12712            } else if (mi.isProc) {
12713                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12714                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12715                pw.println(mi.hasActivities ? ",a" : ",e");
12716            } else {
12717                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12718                pw.println(mi.pss);
12719            }
12720            if (mi.subitems != null) {
12721                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12722                        true, isCompact);
12723            }
12724        }
12725    }
12726
12727    // These are in KB.
12728    static final long[] DUMP_MEM_BUCKETS = new long[] {
12729        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12730        120*1024, 160*1024, 200*1024,
12731        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12732        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12733    };
12734
12735    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12736            boolean stackLike) {
12737        int start = label.lastIndexOf('.');
12738        if (start >= 0) start++;
12739        else start = 0;
12740        int end = label.length();
12741        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12742            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12743                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12744                out.append(bucket);
12745                out.append(stackLike ? "MB." : "MB ");
12746                out.append(label, start, end);
12747                return;
12748            }
12749        }
12750        out.append(memKB/1024);
12751        out.append(stackLike ? "MB." : "MB ");
12752        out.append(label, start, end);
12753    }
12754
12755    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12756            ProcessList.NATIVE_ADJ,
12757            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12758            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12759            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12760            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12761            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12762    };
12763    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12764            "Native",
12765            "System", "Persistent", "Foreground",
12766            "Visible", "Perceptible",
12767            "Heavy Weight", "Backup",
12768            "A Services", "Home",
12769            "Previous", "B Services", "Cached"
12770    };
12771    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12772            "native",
12773            "sys", "pers", "fore",
12774            "vis", "percept",
12775            "heavy", "backup",
12776            "servicea", "home",
12777            "prev", "serviceb", "cached"
12778    };
12779
12780    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12781            long realtime, boolean isCheckinRequest, boolean isCompact) {
12782        if (isCheckinRequest || isCompact) {
12783            // short checkin version
12784            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12785        } else {
12786            pw.println("Applications Memory Usage (kB):");
12787            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12788        }
12789    }
12790
12791    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12792            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12793        boolean dumpDetails = false;
12794        boolean dumpFullDetails = false;
12795        boolean dumpDalvik = false;
12796        boolean oomOnly = false;
12797        boolean isCompact = false;
12798        boolean localOnly = false;
12799
12800        int opti = 0;
12801        while (opti < args.length) {
12802            String opt = args[opti];
12803            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12804                break;
12805            }
12806            opti++;
12807            if ("-a".equals(opt)) {
12808                dumpDetails = true;
12809                dumpFullDetails = true;
12810                dumpDalvik = true;
12811            } else if ("-d".equals(opt)) {
12812                dumpDalvik = true;
12813            } else if ("-c".equals(opt)) {
12814                isCompact = true;
12815            } else if ("--oom".equals(opt)) {
12816                oomOnly = true;
12817            } else if ("--local".equals(opt)) {
12818                localOnly = true;
12819            } else if ("-h".equals(opt)) {
12820                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12821                pw.println("  -a: include all available information for each process.");
12822                pw.println("  -d: include dalvik details when dumping process details.");
12823                pw.println("  -c: dump in a compact machine-parseable representation.");
12824                pw.println("  --oom: only show processes organized by oom adj.");
12825                pw.println("  --local: only collect details locally, don't call process.");
12826                pw.println("If [process] is specified it can be the name or ");
12827                pw.println("pid of a specific process to dump.");
12828                return;
12829            } else {
12830                pw.println("Unknown argument: " + opt + "; use -h for help");
12831            }
12832        }
12833
12834        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12835        long uptime = SystemClock.uptimeMillis();
12836        long realtime = SystemClock.elapsedRealtime();
12837        final long[] tmpLong = new long[1];
12838
12839        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12840        if (procs == null) {
12841            // No Java processes.  Maybe they want to print a native process.
12842            if (args != null && args.length > opti
12843                    && args[opti].charAt(0) != '-') {
12844                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12845                        = new ArrayList<ProcessCpuTracker.Stats>();
12846                updateCpuStatsNow();
12847                int findPid = -1;
12848                try {
12849                    findPid = Integer.parseInt(args[opti]);
12850                } catch (NumberFormatException e) {
12851                }
12852                synchronized (mProcessCpuThread) {
12853                    final int N = mProcessCpuTracker.countStats();
12854                    for (int i=0; i<N; i++) {
12855                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12856                        if (st.pid == findPid || (st.baseName != null
12857                                && st.baseName.equals(args[opti]))) {
12858                            nativeProcs.add(st);
12859                        }
12860                    }
12861                }
12862                if (nativeProcs.size() > 0) {
12863                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12864                            isCompact);
12865                    Debug.MemoryInfo mi = null;
12866                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12867                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12868                        final int pid = r.pid;
12869                        if (!isCheckinRequest && dumpDetails) {
12870                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12871                        }
12872                        if (mi == null) {
12873                            mi = new Debug.MemoryInfo();
12874                        }
12875                        if (dumpDetails || (!brief && !oomOnly)) {
12876                            Debug.getMemoryInfo(pid, mi);
12877                        } else {
12878                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12879                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12880                        }
12881                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12882                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12883                        if (isCheckinRequest) {
12884                            pw.println();
12885                        }
12886                    }
12887                    return;
12888                }
12889            }
12890            pw.println("No process found for: " + args[opti]);
12891            return;
12892        }
12893
12894        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12895            dumpDetails = true;
12896        }
12897
12898        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12899
12900        String[] innerArgs = new String[args.length-opti];
12901        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12902
12903        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12904        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12905        long nativePss=0, dalvikPss=0, otherPss=0;
12906        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12907
12908        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12909        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12910                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12911
12912        long totalPss = 0;
12913        long cachedPss = 0;
12914
12915        Debug.MemoryInfo mi = null;
12916        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12917            final ProcessRecord r = procs.get(i);
12918            final IApplicationThread thread;
12919            final int pid;
12920            final int oomAdj;
12921            final boolean hasActivities;
12922            synchronized (this) {
12923                thread = r.thread;
12924                pid = r.pid;
12925                oomAdj = r.getSetAdjWithServices();
12926                hasActivities = r.activities.size() > 0;
12927            }
12928            if (thread != null) {
12929                if (!isCheckinRequest && dumpDetails) {
12930                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12931                }
12932                if (mi == null) {
12933                    mi = new Debug.MemoryInfo();
12934                }
12935                if (dumpDetails || (!brief && !oomOnly)) {
12936                    Debug.getMemoryInfo(pid, mi);
12937                } else {
12938                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12939                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12940                }
12941                if (dumpDetails) {
12942                    if (localOnly) {
12943                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12944                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12945                        if (isCheckinRequest) {
12946                            pw.println();
12947                        }
12948                    } else {
12949                        try {
12950                            pw.flush();
12951                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12952                                    dumpDalvik, innerArgs);
12953                        } catch (RemoteException e) {
12954                            if (!isCheckinRequest) {
12955                                pw.println("Got RemoteException!");
12956                                pw.flush();
12957                            }
12958                        }
12959                    }
12960                }
12961
12962                final long myTotalPss = mi.getTotalPss();
12963                final long myTotalUss = mi.getTotalUss();
12964
12965                synchronized (this) {
12966                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12967                        // Record this for posterity if the process has been stable.
12968                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12969                    }
12970                }
12971
12972                if (!isCheckinRequest && mi != null) {
12973                    totalPss += myTotalPss;
12974                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12975                            (hasActivities ? " / activities)" : ")"),
12976                            r.processName, myTotalPss, pid, hasActivities);
12977                    procMems.add(pssItem);
12978                    procMemsMap.put(pid, pssItem);
12979
12980                    nativePss += mi.nativePss;
12981                    dalvikPss += mi.dalvikPss;
12982                    otherPss += mi.otherPss;
12983                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12984                        long mem = mi.getOtherPss(j);
12985                        miscPss[j] += mem;
12986                        otherPss -= mem;
12987                    }
12988
12989                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12990                        cachedPss += myTotalPss;
12991                    }
12992
12993                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12994                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12995                                || oomIndex == (oomPss.length-1)) {
12996                            oomPss[oomIndex] += myTotalPss;
12997                            if (oomProcs[oomIndex] == null) {
12998                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12999                            }
13000                            oomProcs[oomIndex].add(pssItem);
13001                            break;
13002                        }
13003                    }
13004                }
13005            }
13006        }
13007
13008        long nativeProcTotalPss = 0;
13009
13010        if (!isCheckinRequest && procs.size() > 1) {
13011            // If we are showing aggregations, also look for native processes to
13012            // include so that our aggregations are more accurate.
13013            updateCpuStatsNow();
13014            synchronized (mProcessCpuThread) {
13015                final int N = mProcessCpuTracker.countStats();
13016                for (int i=0; i<N; i++) {
13017                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13018                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13019                        if (mi == null) {
13020                            mi = new Debug.MemoryInfo();
13021                        }
13022                        if (!brief && !oomOnly) {
13023                            Debug.getMemoryInfo(st.pid, mi);
13024                        } else {
13025                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13026                            mi.nativePrivateDirty = (int)tmpLong[0];
13027                        }
13028
13029                        final long myTotalPss = mi.getTotalPss();
13030                        totalPss += myTotalPss;
13031                        nativeProcTotalPss += myTotalPss;
13032
13033                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13034                                st.name, myTotalPss, st.pid, false);
13035                        procMems.add(pssItem);
13036
13037                        nativePss += mi.nativePss;
13038                        dalvikPss += mi.dalvikPss;
13039                        otherPss += mi.otherPss;
13040                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13041                            long mem = mi.getOtherPss(j);
13042                            miscPss[j] += mem;
13043                            otherPss -= mem;
13044                        }
13045                        oomPss[0] += myTotalPss;
13046                        if (oomProcs[0] == null) {
13047                            oomProcs[0] = new ArrayList<MemItem>();
13048                        }
13049                        oomProcs[0].add(pssItem);
13050                    }
13051                }
13052            }
13053
13054            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13055
13056            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13057            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13058            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13059            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13060                String label = Debug.MemoryInfo.getOtherLabel(j);
13061                catMems.add(new MemItem(label, label, miscPss[j], j));
13062            }
13063
13064            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13065            for (int j=0; j<oomPss.length; j++) {
13066                if (oomPss[j] != 0) {
13067                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13068                            : DUMP_MEM_OOM_LABEL[j];
13069                    MemItem item = new MemItem(label, label, oomPss[j],
13070                            DUMP_MEM_OOM_ADJ[j]);
13071                    item.subitems = oomProcs[j];
13072                    oomMems.add(item);
13073                }
13074            }
13075
13076            if (!brief && !oomOnly && !isCompact) {
13077                pw.println();
13078                pw.println("Total PSS by process:");
13079                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13080                pw.println();
13081            }
13082            if (!isCompact) {
13083                pw.println("Total PSS by OOM adjustment:");
13084            }
13085            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13086            if (!brief && !oomOnly) {
13087                PrintWriter out = categoryPw != null ? categoryPw : pw;
13088                if (!isCompact) {
13089                    out.println();
13090                    out.println("Total PSS by category:");
13091                }
13092                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13093            }
13094            if (!isCompact) {
13095                pw.println();
13096            }
13097            MemInfoReader memInfo = new MemInfoReader();
13098            memInfo.readMemInfo();
13099            if (nativeProcTotalPss > 0) {
13100                synchronized (this) {
13101                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13102                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13103                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13104                            nativeProcTotalPss);
13105                }
13106            }
13107            if (!brief) {
13108                if (!isCompact) {
13109                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13110                    pw.print(" kB (status ");
13111                    switch (mLastMemoryLevel) {
13112                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13113                            pw.println("normal)");
13114                            break;
13115                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13116                            pw.println("moderate)");
13117                            break;
13118                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13119                            pw.println("low)");
13120                            break;
13121                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13122                            pw.println("critical)");
13123                            break;
13124                        default:
13125                            pw.print(mLastMemoryLevel);
13126                            pw.println(")");
13127                            break;
13128                    }
13129                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13130                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13131                            pw.print(cachedPss); pw.print(" cached pss + ");
13132                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13133                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13134                } else {
13135                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13136                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13137                            + memInfo.getFreeSizeKb()); pw.print(",");
13138                    pw.println(totalPss - cachedPss);
13139                }
13140            }
13141            if (!isCompact) {
13142                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13143                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13144                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13145                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13146                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13147                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13148                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13149                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13150                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13151                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13152                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13153            }
13154            if (!brief) {
13155                if (memInfo.getZramTotalSizeKb() != 0) {
13156                    if (!isCompact) {
13157                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13158                                pw.print(" kB physical used for ");
13159                                pw.print(memInfo.getSwapTotalSizeKb()
13160                                        - memInfo.getSwapFreeSizeKb());
13161                                pw.print(" kB in swap (");
13162                                pw.print(memInfo.getSwapTotalSizeKb());
13163                                pw.println(" kB total swap)");
13164                    } else {
13165                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13166                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13167                                pw.println(memInfo.getSwapFreeSizeKb());
13168                    }
13169                }
13170                final int[] SINGLE_LONG_FORMAT = new int[] {
13171                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13172                };
13173                long[] longOut = new long[1];
13174                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13175                        SINGLE_LONG_FORMAT, null, longOut, null);
13176                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13177                longOut[0] = 0;
13178                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13179                        SINGLE_LONG_FORMAT, null, longOut, null);
13180                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13181                longOut[0] = 0;
13182                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13183                        SINGLE_LONG_FORMAT, null, longOut, null);
13184                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13185                longOut[0] = 0;
13186                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13187                        SINGLE_LONG_FORMAT, null, longOut, null);
13188                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13189                if (!isCompact) {
13190                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13191                        pw.print("      KSM: "); pw.print(sharing);
13192                                pw.print(" kB saved from shared ");
13193                                pw.print(shared); pw.println(" kB");
13194                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13195                                pw.print(voltile); pw.println(" kB volatile");
13196                    }
13197                    pw.print("   Tuning: ");
13198                    pw.print(ActivityManager.staticGetMemoryClass());
13199                    pw.print(" (large ");
13200                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13201                    pw.print("), oom ");
13202                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13203                    pw.print(" kB");
13204                    pw.print(", restore limit ");
13205                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13206                    pw.print(" kB");
13207                    if (ActivityManager.isLowRamDeviceStatic()) {
13208                        pw.print(" (low-ram)");
13209                    }
13210                    if (ActivityManager.isHighEndGfx()) {
13211                        pw.print(" (high-end-gfx)");
13212                    }
13213                    pw.println();
13214                } else {
13215                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13216                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13217                    pw.println(voltile);
13218                    pw.print("tuning,");
13219                    pw.print(ActivityManager.staticGetMemoryClass());
13220                    pw.print(',');
13221                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13222                    pw.print(',');
13223                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13224                    if (ActivityManager.isLowRamDeviceStatic()) {
13225                        pw.print(",low-ram");
13226                    }
13227                    if (ActivityManager.isHighEndGfx()) {
13228                        pw.print(",high-end-gfx");
13229                    }
13230                    pw.println();
13231                }
13232            }
13233        }
13234    }
13235
13236    /**
13237     * Searches array of arguments for the specified string
13238     * @param args array of argument strings
13239     * @param value value to search for
13240     * @return true if the value is contained in the array
13241     */
13242    private static boolean scanArgs(String[] args, String value) {
13243        if (args != null) {
13244            for (String arg : args) {
13245                if (value.equals(arg)) {
13246                    return true;
13247                }
13248            }
13249        }
13250        return false;
13251    }
13252
13253    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13254            ContentProviderRecord cpr, boolean always) {
13255        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13256
13257        if (!inLaunching || always) {
13258            synchronized (cpr) {
13259                cpr.launchingApp = null;
13260                cpr.notifyAll();
13261            }
13262            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13263            String names[] = cpr.info.authority.split(";");
13264            for (int j = 0; j < names.length; j++) {
13265                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13266            }
13267        }
13268
13269        for (int i=0; i<cpr.connections.size(); i++) {
13270            ContentProviderConnection conn = cpr.connections.get(i);
13271            if (conn.waiting) {
13272                // If this connection is waiting for the provider, then we don't
13273                // need to mess with its process unless we are always removing
13274                // or for some reason the provider is not currently launching.
13275                if (inLaunching && !always) {
13276                    continue;
13277                }
13278            }
13279            ProcessRecord capp = conn.client;
13280            conn.dead = true;
13281            if (conn.stableCount > 0) {
13282                if (!capp.persistent && capp.thread != null
13283                        && capp.pid != 0
13284                        && capp.pid != MY_PID) {
13285                    killUnneededProcessLocked(capp, "depends on provider "
13286                            + cpr.name.flattenToShortString()
13287                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13288                }
13289            } else if (capp.thread != null && conn.provider.provider != null) {
13290                try {
13291                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13292                } catch (RemoteException e) {
13293                }
13294                // In the protocol here, we don't expect the client to correctly
13295                // clean up this connection, we'll just remove it.
13296                cpr.connections.remove(i);
13297                conn.client.conProviders.remove(conn);
13298            }
13299        }
13300
13301        if (inLaunching && always) {
13302            mLaunchingProviders.remove(cpr);
13303        }
13304        return inLaunching;
13305    }
13306
13307    /**
13308     * Main code for cleaning up a process when it has gone away.  This is
13309     * called both as a result of the process dying, or directly when stopping
13310     * a process when running in single process mode.
13311     */
13312    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13313            boolean restarting, boolean allowRestart, int index) {
13314        if (index >= 0) {
13315            removeLruProcessLocked(app);
13316            ProcessList.remove(app.pid);
13317        }
13318
13319        mProcessesToGc.remove(app);
13320        mPendingPssProcesses.remove(app);
13321
13322        // Dismiss any open dialogs.
13323        if (app.crashDialog != null && !app.forceCrashReport) {
13324            app.crashDialog.dismiss();
13325            app.crashDialog = null;
13326        }
13327        if (app.anrDialog != null) {
13328            app.anrDialog.dismiss();
13329            app.anrDialog = null;
13330        }
13331        if (app.waitDialog != null) {
13332            app.waitDialog.dismiss();
13333            app.waitDialog = null;
13334        }
13335
13336        app.crashing = false;
13337        app.notResponding = false;
13338
13339        app.resetPackageList(mProcessStats);
13340        app.unlinkDeathRecipient();
13341        app.makeInactive(mProcessStats);
13342        app.waitingToKill = null;
13343        app.forcingToForeground = null;
13344        updateProcessForegroundLocked(app, false, false);
13345        app.foregroundActivities = false;
13346        app.hasShownUi = false;
13347        app.treatLikeActivity = false;
13348        app.hasAboveClient = false;
13349        app.hasClientActivities = false;
13350
13351        mServices.killServicesLocked(app, allowRestart);
13352
13353        boolean restart = false;
13354
13355        // Remove published content providers.
13356        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13357            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13358            final boolean always = app.bad || !allowRestart;
13359            if (removeDyingProviderLocked(app, cpr, always) || always) {
13360                // We left the provider in the launching list, need to
13361                // restart it.
13362                restart = true;
13363            }
13364
13365            cpr.provider = null;
13366            cpr.proc = null;
13367        }
13368        app.pubProviders.clear();
13369
13370        // Take care of any launching providers waiting for this process.
13371        if (checkAppInLaunchingProvidersLocked(app, false)) {
13372            restart = true;
13373        }
13374
13375        // Unregister from connected content providers.
13376        if (!app.conProviders.isEmpty()) {
13377            for (int i=0; i<app.conProviders.size(); i++) {
13378                ContentProviderConnection conn = app.conProviders.get(i);
13379                conn.provider.connections.remove(conn);
13380            }
13381            app.conProviders.clear();
13382        }
13383
13384        // At this point there may be remaining entries in mLaunchingProviders
13385        // where we were the only one waiting, so they are no longer of use.
13386        // Look for these and clean up if found.
13387        // XXX Commented out for now.  Trying to figure out a way to reproduce
13388        // the actual situation to identify what is actually going on.
13389        if (false) {
13390            for (int i=0; i<mLaunchingProviders.size(); i++) {
13391                ContentProviderRecord cpr = (ContentProviderRecord)
13392                        mLaunchingProviders.get(i);
13393                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13394                    synchronized (cpr) {
13395                        cpr.launchingApp = null;
13396                        cpr.notifyAll();
13397                    }
13398                }
13399            }
13400        }
13401
13402        skipCurrentReceiverLocked(app);
13403
13404        // Unregister any receivers.
13405        for (int i=app.receivers.size()-1; i>=0; i--) {
13406            removeReceiverLocked(app.receivers.valueAt(i));
13407        }
13408        app.receivers.clear();
13409
13410        // If the app is undergoing backup, tell the backup manager about it
13411        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13412            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13413                    + mBackupTarget.appInfo + " died during backup");
13414            try {
13415                IBackupManager bm = IBackupManager.Stub.asInterface(
13416                        ServiceManager.getService(Context.BACKUP_SERVICE));
13417                bm.agentDisconnected(app.info.packageName);
13418            } catch (RemoteException e) {
13419                // can't happen; backup manager is local
13420            }
13421        }
13422
13423        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13424            ProcessChangeItem item = mPendingProcessChanges.get(i);
13425            if (item.pid == app.pid) {
13426                mPendingProcessChanges.remove(i);
13427                mAvailProcessChanges.add(item);
13428            }
13429        }
13430        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13431
13432        // If the caller is restarting this app, then leave it in its
13433        // current lists and let the caller take care of it.
13434        if (restarting) {
13435            return;
13436        }
13437
13438        if (!app.persistent || app.isolated) {
13439            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13440                    "Removing non-persistent process during cleanup: " + app);
13441            mProcessNames.remove(app.processName, app.uid);
13442            mIsolatedProcesses.remove(app.uid);
13443            if (mHeavyWeightProcess == app) {
13444                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13445                        mHeavyWeightProcess.userId, 0));
13446                mHeavyWeightProcess = null;
13447            }
13448        } else if (!app.removed) {
13449            // This app is persistent, so we need to keep its record around.
13450            // If it is not already on the pending app list, add it there
13451            // and start a new process for it.
13452            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13453                mPersistentStartingProcesses.add(app);
13454                restart = true;
13455            }
13456        }
13457        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13458                "Clean-up removing on hold: " + app);
13459        mProcessesOnHold.remove(app);
13460
13461        if (app == mHomeProcess) {
13462            mHomeProcess = null;
13463        }
13464        if (app == mPreviousProcess) {
13465            mPreviousProcess = null;
13466        }
13467
13468        if (restart && !app.isolated) {
13469            // We have components that still need to be running in the
13470            // process, so re-launch it.
13471            mProcessNames.put(app.processName, app.uid, app);
13472            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13473        } else if (app.pid > 0 && app.pid != MY_PID) {
13474            // Goodbye!
13475            boolean removed;
13476            synchronized (mPidsSelfLocked) {
13477                mPidsSelfLocked.remove(app.pid);
13478                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13479            }
13480            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13481            if (app.isolated) {
13482                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13483            }
13484            app.setPid(0);
13485        }
13486    }
13487
13488    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13489        // Look through the content providers we are waiting to have launched,
13490        // and if any run in this process then either schedule a restart of
13491        // the process or kill the client waiting for it if this process has
13492        // gone bad.
13493        int NL = mLaunchingProviders.size();
13494        boolean restart = false;
13495        for (int i=0; i<NL; i++) {
13496            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13497            if (cpr.launchingApp == app) {
13498                if (!alwaysBad && !app.bad) {
13499                    restart = true;
13500                } else {
13501                    removeDyingProviderLocked(app, cpr, true);
13502                    // cpr should have been removed from mLaunchingProviders
13503                    NL = mLaunchingProviders.size();
13504                    i--;
13505                }
13506            }
13507        }
13508        return restart;
13509    }
13510
13511    // =========================================================
13512    // SERVICES
13513    // =========================================================
13514
13515    @Override
13516    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13517            int flags) {
13518        enforceNotIsolatedCaller("getServices");
13519        synchronized (this) {
13520            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13521        }
13522    }
13523
13524    @Override
13525    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13526        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13527        synchronized (this) {
13528            return mServices.getRunningServiceControlPanelLocked(name);
13529        }
13530    }
13531
13532    @Override
13533    public ComponentName startService(IApplicationThread caller, Intent service,
13534            String resolvedType, int userId) {
13535        enforceNotIsolatedCaller("startService");
13536        // Refuse possible leaked file descriptors
13537        if (service != null && service.hasFileDescriptors() == true) {
13538            throw new IllegalArgumentException("File descriptors passed in Intent");
13539        }
13540
13541        if (DEBUG_SERVICE)
13542            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13543        synchronized(this) {
13544            final int callingPid = Binder.getCallingPid();
13545            final int callingUid = Binder.getCallingUid();
13546            final long origId = Binder.clearCallingIdentity();
13547            ComponentName res = mServices.startServiceLocked(caller, service,
13548                    resolvedType, callingPid, callingUid, userId);
13549            Binder.restoreCallingIdentity(origId);
13550            return res;
13551        }
13552    }
13553
13554    ComponentName startServiceInPackage(int uid,
13555            Intent service, String resolvedType, int userId) {
13556        synchronized(this) {
13557            if (DEBUG_SERVICE)
13558                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13559            final long origId = Binder.clearCallingIdentity();
13560            ComponentName res = mServices.startServiceLocked(null, service,
13561                    resolvedType, -1, uid, userId);
13562            Binder.restoreCallingIdentity(origId);
13563            return res;
13564        }
13565    }
13566
13567    @Override
13568    public int stopService(IApplicationThread caller, Intent service,
13569            String resolvedType, int userId) {
13570        enforceNotIsolatedCaller("stopService");
13571        // Refuse possible leaked file descriptors
13572        if (service != null && service.hasFileDescriptors() == true) {
13573            throw new IllegalArgumentException("File descriptors passed in Intent");
13574        }
13575
13576        synchronized(this) {
13577            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13578        }
13579    }
13580
13581    @Override
13582    public IBinder peekService(Intent service, String resolvedType) {
13583        enforceNotIsolatedCaller("peekService");
13584        // Refuse possible leaked file descriptors
13585        if (service != null && service.hasFileDescriptors() == true) {
13586            throw new IllegalArgumentException("File descriptors passed in Intent");
13587        }
13588        synchronized(this) {
13589            return mServices.peekServiceLocked(service, resolvedType);
13590        }
13591    }
13592
13593    @Override
13594    public boolean stopServiceToken(ComponentName className, IBinder token,
13595            int startId) {
13596        synchronized(this) {
13597            return mServices.stopServiceTokenLocked(className, token, startId);
13598        }
13599    }
13600
13601    @Override
13602    public void setServiceForeground(ComponentName className, IBinder token,
13603            int id, Notification notification, boolean removeNotification) {
13604        synchronized(this) {
13605            mServices.setServiceForegroundLocked(className, token, id, notification,
13606                    removeNotification);
13607        }
13608    }
13609
13610    @Override
13611    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13612            boolean requireFull, String name, String callerPackage) {
13613        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13614                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13615    }
13616
13617    int unsafeConvertIncomingUser(int userId) {
13618        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13619                ? mCurrentUserId : userId;
13620    }
13621
13622    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13623            int allowMode, String name, String callerPackage) {
13624        final int callingUserId = UserHandle.getUserId(callingUid);
13625        if (callingUserId == userId) {
13626            return userId;
13627        }
13628
13629        // Note that we may be accessing mCurrentUserId outside of a lock...
13630        // shouldn't be a big deal, if this is being called outside
13631        // of a locked context there is intrinsically a race with
13632        // the value the caller will receive and someone else changing it.
13633        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13634        // we will switch to the calling user if access to the current user fails.
13635        int targetUserId = unsafeConvertIncomingUser(userId);
13636
13637        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13638            final boolean allow;
13639            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13640                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13641                // If the caller has this permission, they always pass go.  And collect $200.
13642                allow = true;
13643            } else if (allowMode == ALLOW_FULL_ONLY) {
13644                // We require full access, sucks to be you.
13645                allow = false;
13646            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13647                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13648                // If the caller does not have either permission, they are always doomed.
13649                allow = false;
13650            } else if (allowMode == ALLOW_NON_FULL) {
13651                // We are blanket allowing non-full access, you lucky caller!
13652                allow = true;
13653            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13654                // We may or may not allow this depending on whether the two users are
13655                // in the same profile.
13656                synchronized (mUserProfileGroupIdsSelfLocked) {
13657                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13658                            UserInfo.NO_PROFILE_GROUP_ID);
13659                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13660                            UserInfo.NO_PROFILE_GROUP_ID);
13661                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13662                            && callingProfile == targetProfile;
13663                }
13664            } else {
13665                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13666            }
13667            if (!allow) {
13668                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13669                    // In this case, they would like to just execute as their
13670                    // owner user instead of failing.
13671                    targetUserId = callingUserId;
13672                } else {
13673                    StringBuilder builder = new StringBuilder(128);
13674                    builder.append("Permission Denial: ");
13675                    builder.append(name);
13676                    if (callerPackage != null) {
13677                        builder.append(" from ");
13678                        builder.append(callerPackage);
13679                    }
13680                    builder.append(" asks to run as user ");
13681                    builder.append(userId);
13682                    builder.append(" but is calling from user ");
13683                    builder.append(UserHandle.getUserId(callingUid));
13684                    builder.append("; this requires ");
13685                    builder.append(INTERACT_ACROSS_USERS_FULL);
13686                    if (allowMode != ALLOW_FULL_ONLY) {
13687                        builder.append(" or ");
13688                        builder.append(INTERACT_ACROSS_USERS);
13689                    }
13690                    String msg = builder.toString();
13691                    Slog.w(TAG, msg);
13692                    throw new SecurityException(msg);
13693                }
13694            }
13695        }
13696        if (!allowAll && targetUserId < 0) {
13697            throw new IllegalArgumentException(
13698                    "Call does not support special user #" + targetUserId);
13699        }
13700        return targetUserId;
13701    }
13702
13703    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13704            String className, int flags) {
13705        boolean result = false;
13706        // For apps that don't have pre-defined UIDs, check for permission
13707        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13708            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13709                if (ActivityManager.checkUidPermission(
13710                        INTERACT_ACROSS_USERS,
13711                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13712                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13713                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13714                            + " requests FLAG_SINGLE_USER, but app does not hold "
13715                            + INTERACT_ACROSS_USERS;
13716                    Slog.w(TAG, msg);
13717                    throw new SecurityException(msg);
13718                }
13719                // Permission passed
13720                result = true;
13721            }
13722        } else if ("system".equals(componentProcessName)) {
13723            result = true;
13724        } else {
13725            // App with pre-defined UID, check if it's a persistent app
13726            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13727        }
13728        if (DEBUG_MU) {
13729            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13730                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13731        }
13732        return result;
13733    }
13734
13735    /**
13736     * Checks to see if the caller is in the same app as the singleton
13737     * component, or the component is in a special app. It allows special apps
13738     * to export singleton components but prevents exporting singleton
13739     * components for regular apps.
13740     */
13741    boolean isValidSingletonCall(int callingUid, int componentUid) {
13742        int componentAppId = UserHandle.getAppId(componentUid);
13743        return UserHandle.isSameApp(callingUid, componentUid)
13744                || componentAppId == Process.SYSTEM_UID
13745                || componentAppId == Process.PHONE_UID
13746                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13747                        == PackageManager.PERMISSION_GRANTED;
13748    }
13749
13750    public int bindService(IApplicationThread caller, IBinder token,
13751            Intent service, String resolvedType,
13752            IServiceConnection connection, int flags, int userId) {
13753        enforceNotIsolatedCaller("bindService");
13754        // Refuse possible leaked file descriptors
13755        if (service != null && service.hasFileDescriptors() == true) {
13756            throw new IllegalArgumentException("File descriptors passed in Intent");
13757        }
13758
13759        synchronized(this) {
13760            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13761                    connection, flags, userId);
13762        }
13763    }
13764
13765    public boolean unbindService(IServiceConnection connection) {
13766        synchronized (this) {
13767            return mServices.unbindServiceLocked(connection);
13768        }
13769    }
13770
13771    public void publishService(IBinder token, Intent intent, IBinder service) {
13772        // Refuse possible leaked file descriptors
13773        if (intent != null && intent.hasFileDescriptors() == true) {
13774            throw new IllegalArgumentException("File descriptors passed in Intent");
13775        }
13776
13777        synchronized(this) {
13778            if (!(token instanceof ServiceRecord)) {
13779                throw new IllegalArgumentException("Invalid service token");
13780            }
13781            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13782        }
13783    }
13784
13785    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13786        // Refuse possible leaked file descriptors
13787        if (intent != null && intent.hasFileDescriptors() == true) {
13788            throw new IllegalArgumentException("File descriptors passed in Intent");
13789        }
13790
13791        synchronized(this) {
13792            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13793        }
13794    }
13795
13796    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13797        synchronized(this) {
13798            if (!(token instanceof ServiceRecord)) {
13799                throw new IllegalArgumentException("Invalid service token");
13800            }
13801            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13802        }
13803    }
13804
13805    // =========================================================
13806    // BACKUP AND RESTORE
13807    // =========================================================
13808
13809    // Cause the target app to be launched if necessary and its backup agent
13810    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13811    // activity manager to announce its creation.
13812    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13813        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13814        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13815
13816        synchronized(this) {
13817            // !!! TODO: currently no check here that we're already bound
13818            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13819            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13820            synchronized (stats) {
13821                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13822            }
13823
13824            // Backup agent is now in use, its package can't be stopped.
13825            try {
13826                AppGlobals.getPackageManager().setPackageStoppedState(
13827                        app.packageName, false, UserHandle.getUserId(app.uid));
13828            } catch (RemoteException e) {
13829            } catch (IllegalArgumentException e) {
13830                Slog.w(TAG, "Failed trying to unstop package "
13831                        + app.packageName + ": " + e);
13832            }
13833
13834            BackupRecord r = new BackupRecord(ss, app, backupMode);
13835            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13836                    ? new ComponentName(app.packageName, app.backupAgentName)
13837                    : new ComponentName("android", "FullBackupAgent");
13838            // startProcessLocked() returns existing proc's record if it's already running
13839            ProcessRecord proc = startProcessLocked(app.processName, app,
13840                    false, 0, "backup", hostingName, false, false, false);
13841            if (proc == null) {
13842                Slog.e(TAG, "Unable to start backup agent process " + r);
13843                return false;
13844            }
13845
13846            r.app = proc;
13847            mBackupTarget = r;
13848            mBackupAppName = app.packageName;
13849
13850            // Try not to kill the process during backup
13851            updateOomAdjLocked(proc);
13852
13853            // If the process is already attached, schedule the creation of the backup agent now.
13854            // If it is not yet live, this will be done when it attaches to the framework.
13855            if (proc.thread != null) {
13856                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13857                try {
13858                    proc.thread.scheduleCreateBackupAgent(app,
13859                            compatibilityInfoForPackageLocked(app), backupMode);
13860                } catch (RemoteException e) {
13861                    // Will time out on the backup manager side
13862                }
13863            } else {
13864                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13865            }
13866            // Invariants: at this point, the target app process exists and the application
13867            // is either already running or in the process of coming up.  mBackupTarget and
13868            // mBackupAppName describe the app, so that when it binds back to the AM we
13869            // know that it's scheduled for a backup-agent operation.
13870        }
13871
13872        return true;
13873    }
13874
13875    @Override
13876    public void clearPendingBackup() {
13877        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13878        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13879
13880        synchronized (this) {
13881            mBackupTarget = null;
13882            mBackupAppName = null;
13883        }
13884    }
13885
13886    // A backup agent has just come up
13887    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13888        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13889                + " = " + agent);
13890
13891        synchronized(this) {
13892            if (!agentPackageName.equals(mBackupAppName)) {
13893                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13894                return;
13895            }
13896        }
13897
13898        long oldIdent = Binder.clearCallingIdentity();
13899        try {
13900            IBackupManager bm = IBackupManager.Stub.asInterface(
13901                    ServiceManager.getService(Context.BACKUP_SERVICE));
13902            bm.agentConnected(agentPackageName, agent);
13903        } catch (RemoteException e) {
13904            // can't happen; the backup manager service is local
13905        } catch (Exception e) {
13906            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13907            e.printStackTrace();
13908        } finally {
13909            Binder.restoreCallingIdentity(oldIdent);
13910        }
13911    }
13912
13913    // done with this agent
13914    public void unbindBackupAgent(ApplicationInfo appInfo) {
13915        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13916        if (appInfo == null) {
13917            Slog.w(TAG, "unbind backup agent for null app");
13918            return;
13919        }
13920
13921        synchronized(this) {
13922            try {
13923                if (mBackupAppName == null) {
13924                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13925                    return;
13926                }
13927
13928                if (!mBackupAppName.equals(appInfo.packageName)) {
13929                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13930                    return;
13931                }
13932
13933                // Not backing this app up any more; reset its OOM adjustment
13934                final ProcessRecord proc = mBackupTarget.app;
13935                updateOomAdjLocked(proc);
13936
13937                // If the app crashed during backup, 'thread' will be null here
13938                if (proc.thread != null) {
13939                    try {
13940                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13941                                compatibilityInfoForPackageLocked(appInfo));
13942                    } catch (Exception e) {
13943                        Slog.e(TAG, "Exception when unbinding backup agent:");
13944                        e.printStackTrace();
13945                    }
13946                }
13947            } finally {
13948                mBackupTarget = null;
13949                mBackupAppName = null;
13950            }
13951        }
13952    }
13953    // =========================================================
13954    // BROADCASTS
13955    // =========================================================
13956
13957    private final List getStickiesLocked(String action, IntentFilter filter,
13958            List cur, int userId) {
13959        final ContentResolver resolver = mContext.getContentResolver();
13960        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13961        if (stickies == null) {
13962            return cur;
13963        }
13964        final ArrayList<Intent> list = stickies.get(action);
13965        if (list == null) {
13966            return cur;
13967        }
13968        int N = list.size();
13969        for (int i=0; i<N; i++) {
13970            Intent intent = list.get(i);
13971            if (filter.match(resolver, intent, true, TAG) >= 0) {
13972                if (cur == null) {
13973                    cur = new ArrayList<Intent>();
13974                }
13975                cur.add(intent);
13976            }
13977        }
13978        return cur;
13979    }
13980
13981    boolean isPendingBroadcastProcessLocked(int pid) {
13982        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13983                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13984    }
13985
13986    void skipPendingBroadcastLocked(int pid) {
13987            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13988            for (BroadcastQueue queue : mBroadcastQueues) {
13989                queue.skipPendingBroadcastLocked(pid);
13990            }
13991    }
13992
13993    // The app just attached; send any pending broadcasts that it should receive
13994    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13995        boolean didSomething = false;
13996        for (BroadcastQueue queue : mBroadcastQueues) {
13997            didSomething |= queue.sendPendingBroadcastsLocked(app);
13998        }
13999        return didSomething;
14000    }
14001
14002    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14003            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14004        enforceNotIsolatedCaller("registerReceiver");
14005        int callingUid;
14006        int callingPid;
14007        synchronized(this) {
14008            ProcessRecord callerApp = null;
14009            if (caller != null) {
14010                callerApp = getRecordForAppLocked(caller);
14011                if (callerApp == null) {
14012                    throw new SecurityException(
14013                            "Unable to find app for caller " + caller
14014                            + " (pid=" + Binder.getCallingPid()
14015                            + ") when registering receiver " + receiver);
14016                }
14017                if (callerApp.info.uid != Process.SYSTEM_UID &&
14018                        !callerApp.pkgList.containsKey(callerPackage) &&
14019                        !"android".equals(callerPackage)) {
14020                    throw new SecurityException("Given caller package " + callerPackage
14021                            + " is not running in process " + callerApp);
14022                }
14023                callingUid = callerApp.info.uid;
14024                callingPid = callerApp.pid;
14025            } else {
14026                callerPackage = null;
14027                callingUid = Binder.getCallingUid();
14028                callingPid = Binder.getCallingPid();
14029            }
14030
14031            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14032                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14033
14034            List allSticky = null;
14035
14036            // Look for any matching sticky broadcasts...
14037            Iterator actions = filter.actionsIterator();
14038            if (actions != null) {
14039                while (actions.hasNext()) {
14040                    String action = (String)actions.next();
14041                    allSticky = getStickiesLocked(action, filter, allSticky,
14042                            UserHandle.USER_ALL);
14043                    allSticky = getStickiesLocked(action, filter, allSticky,
14044                            UserHandle.getUserId(callingUid));
14045                }
14046            } else {
14047                allSticky = getStickiesLocked(null, filter, allSticky,
14048                        UserHandle.USER_ALL);
14049                allSticky = getStickiesLocked(null, filter, allSticky,
14050                        UserHandle.getUserId(callingUid));
14051            }
14052
14053            // The first sticky in the list is returned directly back to
14054            // the client.
14055            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14056
14057            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14058                    + ": " + sticky);
14059
14060            if (receiver == null) {
14061                return sticky;
14062            }
14063
14064            ReceiverList rl
14065                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14066            if (rl == null) {
14067                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14068                        userId, receiver);
14069                if (rl.app != null) {
14070                    rl.app.receivers.add(rl);
14071                } else {
14072                    try {
14073                        receiver.asBinder().linkToDeath(rl, 0);
14074                    } catch (RemoteException e) {
14075                        return sticky;
14076                    }
14077                    rl.linkedToDeath = true;
14078                }
14079                mRegisteredReceivers.put(receiver.asBinder(), rl);
14080            } else if (rl.uid != callingUid) {
14081                throw new IllegalArgumentException(
14082                        "Receiver requested to register for uid " + callingUid
14083                        + " was previously registered for uid " + rl.uid);
14084            } else if (rl.pid != callingPid) {
14085                throw new IllegalArgumentException(
14086                        "Receiver requested to register for pid " + callingPid
14087                        + " was previously registered for pid " + rl.pid);
14088            } else if (rl.userId != userId) {
14089                throw new IllegalArgumentException(
14090                        "Receiver requested to register for user " + userId
14091                        + " was previously registered for user " + rl.userId);
14092            }
14093            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14094                    permission, callingUid, userId);
14095            rl.add(bf);
14096            if (!bf.debugCheck()) {
14097                Slog.w(TAG, "==> For Dynamic broadast");
14098            }
14099            mReceiverResolver.addFilter(bf);
14100
14101            // Enqueue broadcasts for all existing stickies that match
14102            // this filter.
14103            if (allSticky != null) {
14104                ArrayList receivers = new ArrayList();
14105                receivers.add(bf);
14106
14107                int N = allSticky.size();
14108                for (int i=0; i<N; i++) {
14109                    Intent intent = (Intent)allSticky.get(i);
14110                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14111                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14112                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14113                            null, null, false, true, true, -1);
14114                    queue.enqueueParallelBroadcastLocked(r);
14115                    queue.scheduleBroadcastsLocked();
14116                }
14117            }
14118
14119            return sticky;
14120        }
14121    }
14122
14123    public void unregisterReceiver(IIntentReceiver receiver) {
14124        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14125
14126        final long origId = Binder.clearCallingIdentity();
14127        try {
14128            boolean doTrim = false;
14129
14130            synchronized(this) {
14131                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14132                if (rl != null) {
14133                    if (rl.curBroadcast != null) {
14134                        BroadcastRecord r = rl.curBroadcast;
14135                        final boolean doNext = finishReceiverLocked(
14136                                receiver.asBinder(), r.resultCode, r.resultData,
14137                                r.resultExtras, r.resultAbort);
14138                        if (doNext) {
14139                            doTrim = true;
14140                            r.queue.processNextBroadcast(false);
14141                        }
14142                    }
14143
14144                    if (rl.app != null) {
14145                        rl.app.receivers.remove(rl);
14146                    }
14147                    removeReceiverLocked(rl);
14148                    if (rl.linkedToDeath) {
14149                        rl.linkedToDeath = false;
14150                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14151                    }
14152                }
14153            }
14154
14155            // If we actually concluded any broadcasts, we might now be able
14156            // to trim the recipients' apps from our working set
14157            if (doTrim) {
14158                trimApplications();
14159                return;
14160            }
14161
14162        } finally {
14163            Binder.restoreCallingIdentity(origId);
14164        }
14165    }
14166
14167    void removeReceiverLocked(ReceiverList rl) {
14168        mRegisteredReceivers.remove(rl.receiver.asBinder());
14169        int N = rl.size();
14170        for (int i=0; i<N; i++) {
14171            mReceiverResolver.removeFilter(rl.get(i));
14172        }
14173    }
14174
14175    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14176        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14177            ProcessRecord r = mLruProcesses.get(i);
14178            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14179                try {
14180                    r.thread.dispatchPackageBroadcast(cmd, packages);
14181                } catch (RemoteException ex) {
14182                }
14183            }
14184        }
14185    }
14186
14187    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14188            int[] users) {
14189        List<ResolveInfo> receivers = null;
14190        try {
14191            HashSet<ComponentName> singleUserReceivers = null;
14192            boolean scannedFirstReceivers = false;
14193            for (int user : users) {
14194                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14195                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14196                if (user != 0 && newReceivers != null) {
14197                    // If this is not the primary user, we need to check for
14198                    // any receivers that should be filtered out.
14199                    for (int i=0; i<newReceivers.size(); i++) {
14200                        ResolveInfo ri = newReceivers.get(i);
14201                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14202                            newReceivers.remove(i);
14203                            i--;
14204                        }
14205                    }
14206                }
14207                if (newReceivers != null && newReceivers.size() == 0) {
14208                    newReceivers = null;
14209                }
14210                if (receivers == null) {
14211                    receivers = newReceivers;
14212                } else if (newReceivers != null) {
14213                    // We need to concatenate the additional receivers
14214                    // found with what we have do far.  This would be easy,
14215                    // but we also need to de-dup any receivers that are
14216                    // singleUser.
14217                    if (!scannedFirstReceivers) {
14218                        // Collect any single user receivers we had already retrieved.
14219                        scannedFirstReceivers = true;
14220                        for (int i=0; i<receivers.size(); i++) {
14221                            ResolveInfo ri = receivers.get(i);
14222                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14223                                ComponentName cn = new ComponentName(
14224                                        ri.activityInfo.packageName, ri.activityInfo.name);
14225                                if (singleUserReceivers == null) {
14226                                    singleUserReceivers = new HashSet<ComponentName>();
14227                                }
14228                                singleUserReceivers.add(cn);
14229                            }
14230                        }
14231                    }
14232                    // Add the new results to the existing results, tracking
14233                    // and de-dupping single user receivers.
14234                    for (int i=0; i<newReceivers.size(); i++) {
14235                        ResolveInfo ri = newReceivers.get(i);
14236                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14237                            ComponentName cn = new ComponentName(
14238                                    ri.activityInfo.packageName, ri.activityInfo.name);
14239                            if (singleUserReceivers == null) {
14240                                singleUserReceivers = new HashSet<ComponentName>();
14241                            }
14242                            if (!singleUserReceivers.contains(cn)) {
14243                                singleUserReceivers.add(cn);
14244                                receivers.add(ri);
14245                            }
14246                        } else {
14247                            receivers.add(ri);
14248                        }
14249                    }
14250                }
14251            }
14252        } catch (RemoteException ex) {
14253            // pm is in same process, this will never happen.
14254        }
14255        return receivers;
14256    }
14257
14258    private final int broadcastIntentLocked(ProcessRecord callerApp,
14259            String callerPackage, Intent intent, String resolvedType,
14260            IIntentReceiver resultTo, int resultCode, String resultData,
14261            Bundle map, String requiredPermission, int appOp,
14262            boolean ordered, boolean sticky, int callingPid, int callingUid,
14263            int userId) {
14264        intent = new Intent(intent);
14265
14266        // By default broadcasts do not go to stopped apps.
14267        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14268
14269        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14270            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14271            + " ordered=" + ordered + " userid=" + userId);
14272        if ((resultTo != null) && !ordered) {
14273            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14274        }
14275
14276        userId = handleIncomingUser(callingPid, callingUid, userId,
14277                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14278
14279        // Make sure that the user who is receiving this broadcast is started.
14280        // If not, we will just skip it.
14281
14282
14283        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14284            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14285                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14286                Slog.w(TAG, "Skipping broadcast of " + intent
14287                        + ": user " + userId + " is stopped");
14288                return ActivityManager.BROADCAST_SUCCESS;
14289            }
14290        }
14291
14292        /*
14293         * Prevent non-system code (defined here to be non-persistent
14294         * processes) from sending protected broadcasts.
14295         */
14296        int callingAppId = UserHandle.getAppId(callingUid);
14297        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14298            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14299            || callingAppId == Process.NFC_UID || callingUid == 0) {
14300            // Always okay.
14301        } else if (callerApp == null || !callerApp.persistent) {
14302            try {
14303                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14304                        intent.getAction())) {
14305                    String msg = "Permission Denial: not allowed to send broadcast "
14306                            + intent.getAction() + " from pid="
14307                            + callingPid + ", uid=" + callingUid;
14308                    Slog.w(TAG, msg);
14309                    throw new SecurityException(msg);
14310                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14311                    // Special case for compatibility: we don't want apps to send this,
14312                    // but historically it has not been protected and apps may be using it
14313                    // to poke their own app widget.  So, instead of making it protected,
14314                    // just limit it to the caller.
14315                    if (callerApp == null) {
14316                        String msg = "Permission Denial: not allowed to send broadcast "
14317                                + intent.getAction() + " from unknown caller.";
14318                        Slog.w(TAG, msg);
14319                        throw new SecurityException(msg);
14320                    } else if (intent.getComponent() != null) {
14321                        // They are good enough to send to an explicit component...  verify
14322                        // it is being sent to the calling app.
14323                        if (!intent.getComponent().getPackageName().equals(
14324                                callerApp.info.packageName)) {
14325                            String msg = "Permission Denial: not allowed to send broadcast "
14326                                    + intent.getAction() + " to "
14327                                    + intent.getComponent().getPackageName() + " from "
14328                                    + callerApp.info.packageName;
14329                            Slog.w(TAG, msg);
14330                            throw new SecurityException(msg);
14331                        }
14332                    } else {
14333                        // Limit broadcast to their own package.
14334                        intent.setPackage(callerApp.info.packageName);
14335                    }
14336                }
14337            } catch (RemoteException e) {
14338                Slog.w(TAG, "Remote exception", e);
14339                return ActivityManager.BROADCAST_SUCCESS;
14340            }
14341        }
14342
14343        // Handle special intents: if this broadcast is from the package
14344        // manager about a package being removed, we need to remove all of
14345        // its activities from the history stack.
14346        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14347                intent.getAction());
14348        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14349                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14350                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14351                || uidRemoved) {
14352            if (checkComponentPermission(
14353                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14354                    callingPid, callingUid, -1, true)
14355                    == PackageManager.PERMISSION_GRANTED) {
14356                if (uidRemoved) {
14357                    final Bundle intentExtras = intent.getExtras();
14358                    final int uid = intentExtras != null
14359                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14360                    if (uid >= 0) {
14361                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14362                        synchronized (bs) {
14363                            bs.removeUidStatsLocked(uid);
14364                        }
14365                        mAppOpsService.uidRemoved(uid);
14366                    }
14367                } else {
14368                    // If resources are unavailable just force stop all
14369                    // those packages and flush the attribute cache as well.
14370                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14371                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14372                        if (list != null && (list.length > 0)) {
14373                            for (String pkg : list) {
14374                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14375                                        "storage unmount");
14376                            }
14377                            sendPackageBroadcastLocked(
14378                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14379                        }
14380                    } else {
14381                        Uri data = intent.getData();
14382                        String ssp;
14383                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14384                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14385                                    intent.getAction());
14386                            boolean fullUninstall = removed &&
14387                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14388                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14389                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14390                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14391                                        false, fullUninstall, userId,
14392                                        removed ? "pkg removed" : "pkg changed");
14393                            }
14394                            if (removed) {
14395                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14396                                        new String[] {ssp}, userId);
14397                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14398                                    mAppOpsService.packageRemoved(
14399                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14400
14401                                    // Remove all permissions granted from/to this package
14402                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14403                                }
14404                            }
14405                        }
14406                    }
14407                }
14408            } else {
14409                String msg = "Permission Denial: " + intent.getAction()
14410                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14411                        + ", uid=" + callingUid + ")"
14412                        + " requires "
14413                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14414                Slog.w(TAG, msg);
14415                throw new SecurityException(msg);
14416            }
14417
14418        // Special case for adding a package: by default turn on compatibility
14419        // mode.
14420        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14421            Uri data = intent.getData();
14422            String ssp;
14423            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14424                mCompatModePackages.handlePackageAddedLocked(ssp,
14425                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14426            }
14427        }
14428
14429        /*
14430         * If this is the time zone changed action, queue up a message that will reset the timezone
14431         * of all currently running processes. This message will get queued up before the broadcast
14432         * happens.
14433         */
14434        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14435            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14436        }
14437
14438        /*
14439         * If the user set the time, let all running processes know.
14440         */
14441        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14442            final int is24Hour = intent.getBooleanExtra(
14443                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14444            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14445        }
14446
14447        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14448            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14449        }
14450
14451        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14452            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14453            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14454        }
14455
14456        // Add to the sticky list if requested.
14457        if (sticky) {
14458            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14459                    callingPid, callingUid)
14460                    != PackageManager.PERMISSION_GRANTED) {
14461                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14462                        + callingPid + ", uid=" + callingUid
14463                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14464                Slog.w(TAG, msg);
14465                throw new SecurityException(msg);
14466            }
14467            if (requiredPermission != null) {
14468                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14469                        + " and enforce permission " + requiredPermission);
14470                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14471            }
14472            if (intent.getComponent() != null) {
14473                throw new SecurityException(
14474                        "Sticky broadcasts can't target a specific component");
14475            }
14476            // We use userId directly here, since the "all" target is maintained
14477            // as a separate set of sticky broadcasts.
14478            if (userId != UserHandle.USER_ALL) {
14479                // But first, if this is not a broadcast to all users, then
14480                // make sure it doesn't conflict with an existing broadcast to
14481                // all users.
14482                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14483                        UserHandle.USER_ALL);
14484                if (stickies != null) {
14485                    ArrayList<Intent> list = stickies.get(intent.getAction());
14486                    if (list != null) {
14487                        int N = list.size();
14488                        int i;
14489                        for (i=0; i<N; i++) {
14490                            if (intent.filterEquals(list.get(i))) {
14491                                throw new IllegalArgumentException(
14492                                        "Sticky broadcast " + intent + " for user "
14493                                        + userId + " conflicts with existing global broadcast");
14494                            }
14495                        }
14496                    }
14497                }
14498            }
14499            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14500            if (stickies == null) {
14501                stickies = new ArrayMap<String, ArrayList<Intent>>();
14502                mStickyBroadcasts.put(userId, stickies);
14503            }
14504            ArrayList<Intent> list = stickies.get(intent.getAction());
14505            if (list == null) {
14506                list = new ArrayList<Intent>();
14507                stickies.put(intent.getAction(), list);
14508            }
14509            int N = list.size();
14510            int i;
14511            for (i=0; i<N; i++) {
14512                if (intent.filterEquals(list.get(i))) {
14513                    // This sticky already exists, replace it.
14514                    list.set(i, new Intent(intent));
14515                    break;
14516                }
14517            }
14518            if (i >= N) {
14519                list.add(new Intent(intent));
14520            }
14521        }
14522
14523        int[] users;
14524        if (userId == UserHandle.USER_ALL) {
14525            // Caller wants broadcast to go to all started users.
14526            users = mStartedUserArray;
14527        } else {
14528            // Caller wants broadcast to go to one specific user.
14529            users = new int[] {userId};
14530        }
14531
14532        // Figure out who all will receive this broadcast.
14533        List receivers = null;
14534        List<BroadcastFilter> registeredReceivers = null;
14535        // Need to resolve the intent to interested receivers...
14536        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14537                 == 0) {
14538            receivers = collectReceiverComponents(intent, resolvedType, users);
14539        }
14540        if (intent.getComponent() == null) {
14541            registeredReceivers = mReceiverResolver.queryIntent(intent,
14542                    resolvedType, false, userId);
14543        }
14544
14545        final boolean replacePending =
14546                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14547
14548        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14549                + " replacePending=" + replacePending);
14550
14551        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14552        if (!ordered && NR > 0) {
14553            // If we are not serializing this broadcast, then send the
14554            // registered receivers separately so they don't wait for the
14555            // components to be launched.
14556            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14557            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14558                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14559                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14560                    ordered, sticky, false, userId);
14561            if (DEBUG_BROADCAST) Slog.v(
14562                    TAG, "Enqueueing parallel broadcast " + r);
14563            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14564            if (!replaced) {
14565                queue.enqueueParallelBroadcastLocked(r);
14566                queue.scheduleBroadcastsLocked();
14567            }
14568            registeredReceivers = null;
14569            NR = 0;
14570        }
14571
14572        // Merge into one list.
14573        int ir = 0;
14574        if (receivers != null) {
14575            // A special case for PACKAGE_ADDED: do not allow the package
14576            // being added to see this broadcast.  This prevents them from
14577            // using this as a back door to get run as soon as they are
14578            // installed.  Maybe in the future we want to have a special install
14579            // broadcast or such for apps, but we'd like to deliberately make
14580            // this decision.
14581            String skipPackages[] = null;
14582            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14583                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14584                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14585                Uri data = intent.getData();
14586                if (data != null) {
14587                    String pkgName = data.getSchemeSpecificPart();
14588                    if (pkgName != null) {
14589                        skipPackages = new String[] { pkgName };
14590                    }
14591                }
14592            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14593                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14594            }
14595            if (skipPackages != null && (skipPackages.length > 0)) {
14596                for (String skipPackage : skipPackages) {
14597                    if (skipPackage != null) {
14598                        int NT = receivers.size();
14599                        for (int it=0; it<NT; it++) {
14600                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14601                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14602                                receivers.remove(it);
14603                                it--;
14604                                NT--;
14605                            }
14606                        }
14607                    }
14608                }
14609            }
14610
14611            int NT = receivers != null ? receivers.size() : 0;
14612            int it = 0;
14613            ResolveInfo curt = null;
14614            BroadcastFilter curr = null;
14615            while (it < NT && ir < NR) {
14616                if (curt == null) {
14617                    curt = (ResolveInfo)receivers.get(it);
14618                }
14619                if (curr == null) {
14620                    curr = registeredReceivers.get(ir);
14621                }
14622                if (curr.getPriority() >= curt.priority) {
14623                    // Insert this broadcast record into the final list.
14624                    receivers.add(it, curr);
14625                    ir++;
14626                    curr = null;
14627                    it++;
14628                    NT++;
14629                } else {
14630                    // Skip to the next ResolveInfo in the final list.
14631                    it++;
14632                    curt = null;
14633                }
14634            }
14635        }
14636        while (ir < NR) {
14637            if (receivers == null) {
14638                receivers = new ArrayList();
14639            }
14640            receivers.add(registeredReceivers.get(ir));
14641            ir++;
14642        }
14643
14644        if ((receivers != null && receivers.size() > 0)
14645                || resultTo != null) {
14646            BroadcastQueue queue = broadcastQueueForIntent(intent);
14647            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14648                    callerPackage, callingPid, callingUid, resolvedType,
14649                    requiredPermission, appOp, receivers, resultTo, resultCode,
14650                    resultData, map, ordered, sticky, false, userId);
14651            if (DEBUG_BROADCAST) Slog.v(
14652                    TAG, "Enqueueing ordered broadcast " + r
14653                    + ": prev had " + queue.mOrderedBroadcasts.size());
14654            if (DEBUG_BROADCAST) {
14655                int seq = r.intent.getIntExtra("seq", -1);
14656                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14657            }
14658            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14659            if (!replaced) {
14660                queue.enqueueOrderedBroadcastLocked(r);
14661                queue.scheduleBroadcastsLocked();
14662            }
14663        }
14664
14665        return ActivityManager.BROADCAST_SUCCESS;
14666    }
14667
14668    final Intent verifyBroadcastLocked(Intent intent) {
14669        // Refuse possible leaked file descriptors
14670        if (intent != null && intent.hasFileDescriptors() == true) {
14671            throw new IllegalArgumentException("File descriptors passed in Intent");
14672        }
14673
14674        int flags = intent.getFlags();
14675
14676        if (!mProcessesReady) {
14677            // if the caller really truly claims to know what they're doing, go
14678            // ahead and allow the broadcast without launching any receivers
14679            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14680                intent = new Intent(intent);
14681                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14682            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14683                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14684                        + " before boot completion");
14685                throw new IllegalStateException("Cannot broadcast before boot completed");
14686            }
14687        }
14688
14689        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14690            throw new IllegalArgumentException(
14691                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14692        }
14693
14694        return intent;
14695    }
14696
14697    public final int broadcastIntent(IApplicationThread caller,
14698            Intent intent, String resolvedType, IIntentReceiver resultTo,
14699            int resultCode, String resultData, Bundle map,
14700            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14701        enforceNotIsolatedCaller("broadcastIntent");
14702        synchronized(this) {
14703            intent = verifyBroadcastLocked(intent);
14704
14705            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14706            final int callingPid = Binder.getCallingPid();
14707            final int callingUid = Binder.getCallingUid();
14708            final long origId = Binder.clearCallingIdentity();
14709            int res = broadcastIntentLocked(callerApp,
14710                    callerApp != null ? callerApp.info.packageName : null,
14711                    intent, resolvedType, resultTo,
14712                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14713                    callingPid, callingUid, userId);
14714            Binder.restoreCallingIdentity(origId);
14715            return res;
14716        }
14717    }
14718
14719    int broadcastIntentInPackage(String packageName, int uid,
14720            Intent intent, String resolvedType, IIntentReceiver resultTo,
14721            int resultCode, String resultData, Bundle map,
14722            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14723        synchronized(this) {
14724            intent = verifyBroadcastLocked(intent);
14725
14726            final long origId = Binder.clearCallingIdentity();
14727            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14728                    resultTo, resultCode, resultData, map, requiredPermission,
14729                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14730            Binder.restoreCallingIdentity(origId);
14731            return res;
14732        }
14733    }
14734
14735    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14736        // Refuse possible leaked file descriptors
14737        if (intent != null && intent.hasFileDescriptors() == true) {
14738            throw new IllegalArgumentException("File descriptors passed in Intent");
14739        }
14740
14741        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14742                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14743
14744        synchronized(this) {
14745            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14746                    != PackageManager.PERMISSION_GRANTED) {
14747                String msg = "Permission Denial: unbroadcastIntent() from pid="
14748                        + Binder.getCallingPid()
14749                        + ", uid=" + Binder.getCallingUid()
14750                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14751                Slog.w(TAG, msg);
14752                throw new SecurityException(msg);
14753            }
14754            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14755            if (stickies != null) {
14756                ArrayList<Intent> list = stickies.get(intent.getAction());
14757                if (list != null) {
14758                    int N = list.size();
14759                    int i;
14760                    for (i=0; i<N; i++) {
14761                        if (intent.filterEquals(list.get(i))) {
14762                            list.remove(i);
14763                            break;
14764                        }
14765                    }
14766                    if (list.size() <= 0) {
14767                        stickies.remove(intent.getAction());
14768                    }
14769                }
14770                if (stickies.size() <= 0) {
14771                    mStickyBroadcasts.remove(userId);
14772                }
14773            }
14774        }
14775    }
14776
14777    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14778            String resultData, Bundle resultExtras, boolean resultAbort) {
14779        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14780        if (r == null) {
14781            Slog.w(TAG, "finishReceiver called but not found on queue");
14782            return false;
14783        }
14784
14785        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14786    }
14787
14788    void backgroundServicesFinishedLocked(int userId) {
14789        for (BroadcastQueue queue : mBroadcastQueues) {
14790            queue.backgroundServicesFinishedLocked(userId);
14791        }
14792    }
14793
14794    public void finishReceiver(IBinder who, int resultCode, String resultData,
14795            Bundle resultExtras, boolean resultAbort) {
14796        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14797
14798        // Refuse possible leaked file descriptors
14799        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14800            throw new IllegalArgumentException("File descriptors passed in Bundle");
14801        }
14802
14803        final long origId = Binder.clearCallingIdentity();
14804        try {
14805            boolean doNext = false;
14806            BroadcastRecord r;
14807
14808            synchronized(this) {
14809                r = broadcastRecordForReceiverLocked(who);
14810                if (r != null) {
14811                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14812                        resultData, resultExtras, resultAbort, true);
14813                }
14814            }
14815
14816            if (doNext) {
14817                r.queue.processNextBroadcast(false);
14818            }
14819            trimApplications();
14820        } finally {
14821            Binder.restoreCallingIdentity(origId);
14822        }
14823    }
14824
14825    // =========================================================
14826    // INSTRUMENTATION
14827    // =========================================================
14828
14829    public boolean startInstrumentation(ComponentName className,
14830            String profileFile, int flags, Bundle arguments,
14831            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14832            int userId, String abiOverride) {
14833        enforceNotIsolatedCaller("startInstrumentation");
14834        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14835                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14836        // Refuse possible leaked file descriptors
14837        if (arguments != null && arguments.hasFileDescriptors()) {
14838            throw new IllegalArgumentException("File descriptors passed in Bundle");
14839        }
14840
14841        synchronized(this) {
14842            InstrumentationInfo ii = null;
14843            ApplicationInfo ai = null;
14844            try {
14845                ii = mContext.getPackageManager().getInstrumentationInfo(
14846                    className, STOCK_PM_FLAGS);
14847                ai = AppGlobals.getPackageManager().getApplicationInfo(
14848                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14849            } catch (PackageManager.NameNotFoundException e) {
14850            } catch (RemoteException e) {
14851            }
14852            if (ii == null) {
14853                reportStartInstrumentationFailure(watcher, className,
14854                        "Unable to find instrumentation info for: " + className);
14855                return false;
14856            }
14857            if (ai == null) {
14858                reportStartInstrumentationFailure(watcher, className,
14859                        "Unable to find instrumentation target package: " + ii.targetPackage);
14860                return false;
14861            }
14862
14863            int match = mContext.getPackageManager().checkSignatures(
14864                    ii.targetPackage, ii.packageName);
14865            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14866                String msg = "Permission Denial: starting instrumentation "
14867                        + className + " from pid="
14868                        + Binder.getCallingPid()
14869                        + ", uid=" + Binder.getCallingPid()
14870                        + " not allowed because package " + ii.packageName
14871                        + " does not have a signature matching the target "
14872                        + ii.targetPackage;
14873                reportStartInstrumentationFailure(watcher, className, msg);
14874                throw new SecurityException(msg);
14875            }
14876
14877            final long origId = Binder.clearCallingIdentity();
14878            // Instrumentation can kill and relaunch even persistent processes
14879            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14880                    "start instr");
14881            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14882            app.instrumentationClass = className;
14883            app.instrumentationInfo = ai;
14884            app.instrumentationProfileFile = profileFile;
14885            app.instrumentationArguments = arguments;
14886            app.instrumentationWatcher = watcher;
14887            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14888            app.instrumentationResultClass = className;
14889            Binder.restoreCallingIdentity(origId);
14890        }
14891
14892        return true;
14893    }
14894
14895    /**
14896     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14897     * error to the logs, but if somebody is watching, send the report there too.  This enables
14898     * the "am" command to report errors with more information.
14899     *
14900     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14901     * @param cn The component name of the instrumentation.
14902     * @param report The error report.
14903     */
14904    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14905            ComponentName cn, String report) {
14906        Slog.w(TAG, report);
14907        try {
14908            if (watcher != null) {
14909                Bundle results = new Bundle();
14910                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14911                results.putString("Error", report);
14912                watcher.instrumentationStatus(cn, -1, results);
14913            }
14914        } catch (RemoteException e) {
14915            Slog.w(TAG, e);
14916        }
14917    }
14918
14919    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14920        if (app.instrumentationWatcher != null) {
14921            try {
14922                // NOTE:  IInstrumentationWatcher *must* be oneway here
14923                app.instrumentationWatcher.instrumentationFinished(
14924                    app.instrumentationClass,
14925                    resultCode,
14926                    results);
14927            } catch (RemoteException e) {
14928            }
14929        }
14930        if (app.instrumentationUiAutomationConnection != null) {
14931            try {
14932                app.instrumentationUiAutomationConnection.shutdown();
14933            } catch (RemoteException re) {
14934                /* ignore */
14935            }
14936            // Only a UiAutomation can set this flag and now that
14937            // it is finished we make sure it is reset to its default.
14938            mUserIsMonkey = false;
14939        }
14940        app.instrumentationWatcher = null;
14941        app.instrumentationUiAutomationConnection = null;
14942        app.instrumentationClass = null;
14943        app.instrumentationInfo = null;
14944        app.instrumentationProfileFile = null;
14945        app.instrumentationArguments = null;
14946
14947        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14948                "finished inst");
14949    }
14950
14951    public void finishInstrumentation(IApplicationThread target,
14952            int resultCode, Bundle results) {
14953        int userId = UserHandle.getCallingUserId();
14954        // Refuse possible leaked file descriptors
14955        if (results != null && results.hasFileDescriptors()) {
14956            throw new IllegalArgumentException("File descriptors passed in Intent");
14957        }
14958
14959        synchronized(this) {
14960            ProcessRecord app = getRecordForAppLocked(target);
14961            if (app == null) {
14962                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14963                return;
14964            }
14965            final long origId = Binder.clearCallingIdentity();
14966            finishInstrumentationLocked(app, resultCode, results);
14967            Binder.restoreCallingIdentity(origId);
14968        }
14969    }
14970
14971    // =========================================================
14972    // CONFIGURATION
14973    // =========================================================
14974
14975    public ConfigurationInfo getDeviceConfigurationInfo() {
14976        ConfigurationInfo config = new ConfigurationInfo();
14977        synchronized (this) {
14978            config.reqTouchScreen = mConfiguration.touchscreen;
14979            config.reqKeyboardType = mConfiguration.keyboard;
14980            config.reqNavigation = mConfiguration.navigation;
14981            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14982                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14983                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14984            }
14985            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14986                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14987                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14988            }
14989            config.reqGlEsVersion = GL_ES_VERSION;
14990        }
14991        return config;
14992    }
14993
14994    ActivityStack getFocusedStack() {
14995        return mStackSupervisor.getFocusedStack();
14996    }
14997
14998    public Configuration getConfiguration() {
14999        Configuration ci;
15000        synchronized(this) {
15001            ci = new Configuration(mConfiguration);
15002        }
15003        return ci;
15004    }
15005
15006    public void updatePersistentConfiguration(Configuration values) {
15007        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15008                "updateConfiguration()");
15009        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15010                "updateConfiguration()");
15011        if (values == null) {
15012            throw new NullPointerException("Configuration must not be null");
15013        }
15014
15015        synchronized(this) {
15016            final long origId = Binder.clearCallingIdentity();
15017            updateConfigurationLocked(values, null, true, false);
15018            Binder.restoreCallingIdentity(origId);
15019        }
15020    }
15021
15022    public void updateConfiguration(Configuration values) {
15023        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15024                "updateConfiguration()");
15025
15026        synchronized(this) {
15027            if (values == null && mWindowManager != null) {
15028                // sentinel: fetch the current configuration from the window manager
15029                values = mWindowManager.computeNewConfiguration();
15030            }
15031
15032            if (mWindowManager != null) {
15033                mProcessList.applyDisplaySize(mWindowManager);
15034            }
15035
15036            final long origId = Binder.clearCallingIdentity();
15037            if (values != null) {
15038                Settings.System.clearConfiguration(values);
15039            }
15040            updateConfigurationLocked(values, null, false, false);
15041            Binder.restoreCallingIdentity(origId);
15042        }
15043    }
15044
15045    /**
15046     * Do either or both things: (1) change the current configuration, and (2)
15047     * make sure the given activity is running with the (now) current
15048     * configuration.  Returns true if the activity has been left running, or
15049     * false if <var>starting</var> is being destroyed to match the new
15050     * configuration.
15051     * @param persistent TODO
15052     */
15053    boolean updateConfigurationLocked(Configuration values,
15054            ActivityRecord starting, boolean persistent, boolean initLocale) {
15055        int changes = 0;
15056
15057        if (values != null) {
15058            Configuration newConfig = new Configuration(mConfiguration);
15059            changes = newConfig.updateFrom(values);
15060            if (changes != 0) {
15061                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15062                    Slog.i(TAG, "Updating configuration to: " + values);
15063                }
15064
15065                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15066
15067                if (values.locale != null && !initLocale) {
15068                    saveLocaleLocked(values.locale,
15069                                     !values.locale.equals(mConfiguration.locale),
15070                                     values.userSetLocale);
15071                }
15072
15073                mConfigurationSeq++;
15074                if (mConfigurationSeq <= 0) {
15075                    mConfigurationSeq = 1;
15076                }
15077                newConfig.seq = mConfigurationSeq;
15078                mConfiguration = newConfig;
15079                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15080                //mUsageStatsService.noteStartConfig(newConfig);
15081
15082                final Configuration configCopy = new Configuration(mConfiguration);
15083
15084                // TODO: If our config changes, should we auto dismiss any currently
15085                // showing dialogs?
15086                mShowDialogs = shouldShowDialogs(newConfig);
15087
15088                AttributeCache ac = AttributeCache.instance();
15089                if (ac != null) {
15090                    ac.updateConfiguration(configCopy);
15091                }
15092
15093                // Make sure all resources in our process are updated
15094                // right now, so that anyone who is going to retrieve
15095                // resource values after we return will be sure to get
15096                // the new ones.  This is especially important during
15097                // boot, where the first config change needs to guarantee
15098                // all resources have that config before following boot
15099                // code is executed.
15100                mSystemThread.applyConfigurationToResources(configCopy);
15101
15102                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15103                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15104                    msg.obj = new Configuration(configCopy);
15105                    mHandler.sendMessage(msg);
15106                }
15107
15108                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15109                    ProcessRecord app = mLruProcesses.get(i);
15110                    try {
15111                        if (app.thread != null) {
15112                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15113                                    + app.processName + " new config " + mConfiguration);
15114                            app.thread.scheduleConfigurationChanged(configCopy);
15115                        }
15116                    } catch (Exception e) {
15117                    }
15118                }
15119                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15120                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15121                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15122                        | Intent.FLAG_RECEIVER_FOREGROUND);
15123                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15124                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15125                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15126                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15127                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15128                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15129                    broadcastIntentLocked(null, null, intent,
15130                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15131                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15132                }
15133            }
15134        }
15135
15136        boolean kept = true;
15137        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15138        // mainStack is null during startup.
15139        if (mainStack != null) {
15140            if (changes != 0 && starting == null) {
15141                // If the configuration changed, and the caller is not already
15142                // in the process of starting an activity, then find the top
15143                // activity to check if its configuration needs to change.
15144                starting = mainStack.topRunningActivityLocked(null);
15145            }
15146
15147            if (starting != null) {
15148                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15149                // And we need to make sure at this point that all other activities
15150                // are made visible with the correct configuration.
15151                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15152            }
15153        }
15154
15155        if (values != null && mWindowManager != null) {
15156            mWindowManager.setNewConfiguration(mConfiguration);
15157        }
15158
15159        return kept;
15160    }
15161
15162    /**
15163     * Decide based on the configuration whether we should shouw the ANR,
15164     * crash, etc dialogs.  The idea is that if there is no affordnace to
15165     * press the on-screen buttons, we shouldn't show the dialog.
15166     *
15167     * A thought: SystemUI might also want to get told about this, the Power
15168     * dialog / global actions also might want different behaviors.
15169     */
15170    private static final boolean shouldShowDialogs(Configuration config) {
15171        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15172                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15173    }
15174
15175    /**
15176     * Save the locale.  You must be inside a synchronized (this) block.
15177     */
15178    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15179        if(isDiff) {
15180            SystemProperties.set("user.language", l.getLanguage());
15181            SystemProperties.set("user.region", l.getCountry());
15182        }
15183
15184        if(isPersist) {
15185            SystemProperties.set("persist.sys.language", l.getLanguage());
15186            SystemProperties.set("persist.sys.country", l.getCountry());
15187            SystemProperties.set("persist.sys.localevar", l.getVariant());
15188        }
15189    }
15190
15191    @Override
15192    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15193        ActivityRecord srec = ActivityRecord.forToken(token);
15194        return srec != null && srec.task.affinity != null &&
15195                srec.task.affinity.equals(destAffinity);
15196    }
15197
15198    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15199            Intent resultData) {
15200
15201        synchronized (this) {
15202            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15203            if (stack != null) {
15204                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15205            }
15206            return false;
15207        }
15208    }
15209
15210    public int getLaunchedFromUid(IBinder activityToken) {
15211        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15212        if (srec == null) {
15213            return -1;
15214        }
15215        return srec.launchedFromUid;
15216    }
15217
15218    public String getLaunchedFromPackage(IBinder activityToken) {
15219        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15220        if (srec == null) {
15221            return null;
15222        }
15223        return srec.launchedFromPackage;
15224    }
15225
15226    // =========================================================
15227    // LIFETIME MANAGEMENT
15228    // =========================================================
15229
15230    // Returns which broadcast queue the app is the current [or imminent] receiver
15231    // on, or 'null' if the app is not an active broadcast recipient.
15232    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15233        BroadcastRecord r = app.curReceiver;
15234        if (r != null) {
15235            return r.queue;
15236        }
15237
15238        // It's not the current receiver, but it might be starting up to become one
15239        synchronized (this) {
15240            for (BroadcastQueue queue : mBroadcastQueues) {
15241                r = queue.mPendingBroadcast;
15242                if (r != null && r.curApp == app) {
15243                    // found it; report which queue it's in
15244                    return queue;
15245                }
15246            }
15247        }
15248
15249        return null;
15250    }
15251
15252    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15253            boolean doingAll, long now) {
15254        if (mAdjSeq == app.adjSeq) {
15255            // This adjustment has already been computed.
15256            return app.curRawAdj;
15257        }
15258
15259        if (app.thread == null) {
15260            app.adjSeq = mAdjSeq;
15261            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15262            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15263            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15264        }
15265
15266        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15267        app.adjSource = null;
15268        app.adjTarget = null;
15269        app.empty = false;
15270        app.cached = false;
15271
15272        final int activitiesSize = app.activities.size();
15273
15274        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15275            // The max adjustment doesn't allow this app to be anything
15276            // below foreground, so it is not worth doing work for it.
15277            app.adjType = "fixed";
15278            app.adjSeq = mAdjSeq;
15279            app.curRawAdj = app.maxAdj;
15280            app.foregroundActivities = false;
15281            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15282            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15283            // System processes can do UI, and when they do we want to have
15284            // them trim their memory after the user leaves the UI.  To
15285            // facilitate this, here we need to determine whether or not it
15286            // is currently showing UI.
15287            app.systemNoUi = true;
15288            if (app == TOP_APP) {
15289                app.systemNoUi = false;
15290            } else if (activitiesSize > 0) {
15291                for (int j = 0; j < activitiesSize; j++) {
15292                    final ActivityRecord r = app.activities.get(j);
15293                    if (r.visible) {
15294                        app.systemNoUi = false;
15295                    }
15296                }
15297            }
15298            if (!app.systemNoUi) {
15299                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15300            }
15301            return (app.curAdj=app.maxAdj);
15302        }
15303
15304        app.systemNoUi = false;
15305
15306        // Determine the importance of the process, starting with most
15307        // important to least, and assign an appropriate OOM adjustment.
15308        int adj;
15309        int schedGroup;
15310        int procState;
15311        boolean foregroundActivities = false;
15312        BroadcastQueue queue;
15313        if (app == TOP_APP) {
15314            // The last app on the list is the foreground app.
15315            adj = ProcessList.FOREGROUND_APP_ADJ;
15316            schedGroup = Process.THREAD_GROUP_DEFAULT;
15317            app.adjType = "top-activity";
15318            foregroundActivities = true;
15319            procState = ActivityManager.PROCESS_STATE_TOP;
15320        } else if (app.instrumentationClass != null) {
15321            // Don't want to kill running instrumentation.
15322            adj = ProcessList.FOREGROUND_APP_ADJ;
15323            schedGroup = Process.THREAD_GROUP_DEFAULT;
15324            app.adjType = "instrumentation";
15325            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15326        } else if ((queue = isReceivingBroadcast(app)) != null) {
15327            // An app that is currently receiving a broadcast also
15328            // counts as being in the foreground for OOM killer purposes.
15329            // It's placed in a sched group based on the nature of the
15330            // broadcast as reflected by which queue it's active in.
15331            adj = ProcessList.FOREGROUND_APP_ADJ;
15332            schedGroup = (queue == mFgBroadcastQueue)
15333                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15334            app.adjType = "broadcast";
15335            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15336        } else if (app.executingServices.size() > 0) {
15337            // An app that is currently executing a service callback also
15338            // counts as being in the foreground.
15339            adj = ProcessList.FOREGROUND_APP_ADJ;
15340            schedGroup = app.execServicesFg ?
15341                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15342            app.adjType = "exec-service";
15343            procState = ActivityManager.PROCESS_STATE_SERVICE;
15344            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15345        } else {
15346            // As far as we know the process is empty.  We may change our mind later.
15347            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15348            // At this point we don't actually know the adjustment.  Use the cached adj
15349            // value that the caller wants us to.
15350            adj = cachedAdj;
15351            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15352            app.cached = true;
15353            app.empty = true;
15354            app.adjType = "cch-empty";
15355        }
15356
15357        // Examine all activities if not already foreground.
15358        if (!foregroundActivities && activitiesSize > 0) {
15359            for (int j = 0; j < activitiesSize; j++) {
15360                final ActivityRecord r = app.activities.get(j);
15361                if (r.app != app) {
15362                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15363                            + app + "?!?");
15364                    continue;
15365                }
15366                if (r.visible) {
15367                    // App has a visible activity; only upgrade adjustment.
15368                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15369                        adj = ProcessList.VISIBLE_APP_ADJ;
15370                        app.adjType = "visible";
15371                    }
15372                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15373                        procState = ActivityManager.PROCESS_STATE_TOP;
15374                    }
15375                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15376                    app.cached = false;
15377                    app.empty = false;
15378                    foregroundActivities = true;
15379                    break;
15380                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15381                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15382                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15383                        app.adjType = "pausing";
15384                    }
15385                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15386                        procState = ActivityManager.PROCESS_STATE_TOP;
15387                    }
15388                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15389                    app.cached = false;
15390                    app.empty = false;
15391                    foregroundActivities = true;
15392                } else if (r.state == ActivityState.STOPPING) {
15393                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15394                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15395                        app.adjType = "stopping";
15396                    }
15397                    // For the process state, we will at this point consider the
15398                    // process to be cached.  It will be cached either as an activity
15399                    // or empty depending on whether the activity is finishing.  We do
15400                    // this so that we can treat the process as cached for purposes of
15401                    // memory trimming (determing current memory level, trim command to
15402                    // send to process) since there can be an arbitrary number of stopping
15403                    // processes and they should soon all go into the cached state.
15404                    if (!r.finishing) {
15405                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15406                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15407                        }
15408                    }
15409                    app.cached = false;
15410                    app.empty = false;
15411                    foregroundActivities = true;
15412                } else {
15413                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15414                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15415                        app.adjType = "cch-act";
15416                    }
15417                }
15418            }
15419        }
15420
15421        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15422            if (app.foregroundServices) {
15423                // The user is aware of this app, so make it visible.
15424                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15425                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15426                app.cached = false;
15427                app.adjType = "fg-service";
15428                schedGroup = Process.THREAD_GROUP_DEFAULT;
15429            } else if (app.forcingToForeground != null) {
15430                // The user is aware of this app, so make it visible.
15431                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15432                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15433                app.cached = false;
15434                app.adjType = "force-fg";
15435                app.adjSource = app.forcingToForeground;
15436                schedGroup = Process.THREAD_GROUP_DEFAULT;
15437            }
15438        }
15439
15440        if (app == mHeavyWeightProcess) {
15441            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15442                // We don't want to kill the current heavy-weight process.
15443                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15444                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15445                app.cached = false;
15446                app.adjType = "heavy";
15447            }
15448            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15449                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15450            }
15451        }
15452
15453        if (app == mHomeProcess) {
15454            if (adj > ProcessList.HOME_APP_ADJ) {
15455                // This process is hosting what we currently consider to be the
15456                // home app, so we don't want to let it go into the background.
15457                adj = ProcessList.HOME_APP_ADJ;
15458                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15459                app.cached = false;
15460                app.adjType = "home";
15461            }
15462            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15463                procState = ActivityManager.PROCESS_STATE_HOME;
15464            }
15465        }
15466
15467        if (app == mPreviousProcess && app.activities.size() > 0) {
15468            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15469                // This was the previous process that showed UI to the user.
15470                // We want to try to keep it around more aggressively, to give
15471                // a good experience around switching between two apps.
15472                adj = ProcessList.PREVIOUS_APP_ADJ;
15473                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15474                app.cached = false;
15475                app.adjType = "previous";
15476            }
15477            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15478                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15479            }
15480        }
15481
15482        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15483                + " reason=" + app.adjType);
15484
15485        // By default, we use the computed adjustment.  It may be changed if
15486        // there are applications dependent on our services or providers, but
15487        // this gives us a baseline and makes sure we don't get into an
15488        // infinite recursion.
15489        app.adjSeq = mAdjSeq;
15490        app.curRawAdj = adj;
15491        app.hasStartedServices = false;
15492
15493        if (mBackupTarget != null && app == mBackupTarget.app) {
15494            // If possible we want to avoid killing apps while they're being backed up
15495            if (adj > ProcessList.BACKUP_APP_ADJ) {
15496                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15497                adj = ProcessList.BACKUP_APP_ADJ;
15498                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15499                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15500                }
15501                app.adjType = "backup";
15502                app.cached = false;
15503            }
15504            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15505                procState = ActivityManager.PROCESS_STATE_BACKUP;
15506            }
15507        }
15508
15509        boolean mayBeTop = false;
15510
15511        for (int is = app.services.size()-1;
15512                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15513                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15514                        || procState > ActivityManager.PROCESS_STATE_TOP);
15515                is--) {
15516            ServiceRecord s = app.services.valueAt(is);
15517            if (s.startRequested) {
15518                app.hasStartedServices = true;
15519                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15520                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15521                }
15522                if (app.hasShownUi && app != mHomeProcess) {
15523                    // If this process has shown some UI, let it immediately
15524                    // go to the LRU list because it may be pretty heavy with
15525                    // UI stuff.  We'll tag it with a label just to help
15526                    // debug and understand what is going on.
15527                    if (adj > ProcessList.SERVICE_ADJ) {
15528                        app.adjType = "cch-started-ui-services";
15529                    }
15530                } else {
15531                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15532                        // This service has seen some activity within
15533                        // recent memory, so we will keep its process ahead
15534                        // of the background processes.
15535                        if (adj > ProcessList.SERVICE_ADJ) {
15536                            adj = ProcessList.SERVICE_ADJ;
15537                            app.adjType = "started-services";
15538                            app.cached = false;
15539                        }
15540                    }
15541                    // If we have let the service slide into the background
15542                    // state, still have some text describing what it is doing
15543                    // even though the service no longer has an impact.
15544                    if (adj > ProcessList.SERVICE_ADJ) {
15545                        app.adjType = "cch-started-services";
15546                    }
15547                }
15548            }
15549            for (int conni = s.connections.size()-1;
15550                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15551                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15552                            || procState > ActivityManager.PROCESS_STATE_TOP);
15553                    conni--) {
15554                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15555                for (int i = 0;
15556                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15557                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15558                                || procState > ActivityManager.PROCESS_STATE_TOP);
15559                        i++) {
15560                    // XXX should compute this based on the max of
15561                    // all connected clients.
15562                    ConnectionRecord cr = clist.get(i);
15563                    if (cr.binding.client == app) {
15564                        // Binding to ourself is not interesting.
15565                        continue;
15566                    }
15567                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15568                        ProcessRecord client = cr.binding.client;
15569                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15570                                TOP_APP, doingAll, now);
15571                        int clientProcState = client.curProcState;
15572                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15573                            // If the other app is cached for any reason, for purposes here
15574                            // we are going to consider it empty.  The specific cached state
15575                            // doesn't propagate except under certain conditions.
15576                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15577                        }
15578                        String adjType = null;
15579                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15580                            // Not doing bind OOM management, so treat
15581                            // this guy more like a started service.
15582                            if (app.hasShownUi && app != mHomeProcess) {
15583                                // If this process has shown some UI, let it immediately
15584                                // go to the LRU list because it may be pretty heavy with
15585                                // UI stuff.  We'll tag it with a label just to help
15586                                // debug and understand what is going on.
15587                                if (adj > clientAdj) {
15588                                    adjType = "cch-bound-ui-services";
15589                                }
15590                                app.cached = false;
15591                                clientAdj = adj;
15592                                clientProcState = procState;
15593                            } else {
15594                                if (now >= (s.lastActivity
15595                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15596                                    // This service has not seen activity within
15597                                    // recent memory, so allow it to drop to the
15598                                    // LRU list if there is no other reason to keep
15599                                    // it around.  We'll also tag it with a label just
15600                                    // to help debug and undertand what is going on.
15601                                    if (adj > clientAdj) {
15602                                        adjType = "cch-bound-services";
15603                                    }
15604                                    clientAdj = adj;
15605                                }
15606                            }
15607                        }
15608                        if (adj > clientAdj) {
15609                            // If this process has recently shown UI, and
15610                            // the process that is binding to it is less
15611                            // important than being visible, then we don't
15612                            // care about the binding as much as we care
15613                            // about letting this process get into the LRU
15614                            // list to be killed and restarted if needed for
15615                            // memory.
15616                            if (app.hasShownUi && app != mHomeProcess
15617                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15618                                adjType = "cch-bound-ui-services";
15619                            } else {
15620                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15621                                        |Context.BIND_IMPORTANT)) != 0) {
15622                                    adj = clientAdj;
15623                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15624                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15625                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15626                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15627                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15628                                    adj = clientAdj;
15629                                } else {
15630                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15631                                        adj = ProcessList.VISIBLE_APP_ADJ;
15632                                    }
15633                                }
15634                                if (!client.cached) {
15635                                    app.cached = false;
15636                                }
15637                                adjType = "service";
15638                            }
15639                        }
15640                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15641                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15642                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15643                            }
15644                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15645                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15646                                    // Special handling of clients who are in the top state.
15647                                    // We *may* want to consider this process to be in the
15648                                    // top state as well, but only if there is not another
15649                                    // reason for it to be running.  Being on the top is a
15650                                    // special state, meaning you are specifically running
15651                                    // for the current top app.  If the process is already
15652                                    // running in the background for some other reason, it
15653                                    // is more important to continue considering it to be
15654                                    // in the background state.
15655                                    mayBeTop = true;
15656                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15657                                } else {
15658                                    // Special handling for above-top states (persistent
15659                                    // processes).  These should not bring the current process
15660                                    // into the top state, since they are not on top.  Instead
15661                                    // give them the best state after that.
15662                                    clientProcState =
15663                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15664                                }
15665                            }
15666                        } else {
15667                            if (clientProcState <
15668                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15669                                clientProcState =
15670                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15671                            }
15672                        }
15673                        if (procState > clientProcState) {
15674                            procState = clientProcState;
15675                        }
15676                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15677                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15678                            app.pendingUiClean = true;
15679                        }
15680                        if (adjType != null) {
15681                            app.adjType = adjType;
15682                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15683                                    .REASON_SERVICE_IN_USE;
15684                            app.adjSource = cr.binding.client;
15685                            app.adjSourceProcState = clientProcState;
15686                            app.adjTarget = s.name;
15687                        }
15688                    }
15689                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15690                        app.treatLikeActivity = true;
15691                    }
15692                    final ActivityRecord a = cr.activity;
15693                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15694                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15695                                (a.visible || a.state == ActivityState.RESUMED
15696                                 || a.state == ActivityState.PAUSING)) {
15697                            adj = ProcessList.FOREGROUND_APP_ADJ;
15698                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15699                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15700                            }
15701                            app.cached = false;
15702                            app.adjType = "service";
15703                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15704                                    .REASON_SERVICE_IN_USE;
15705                            app.adjSource = a;
15706                            app.adjSourceProcState = procState;
15707                            app.adjTarget = s.name;
15708                        }
15709                    }
15710                }
15711            }
15712        }
15713
15714        for (int provi = app.pubProviders.size()-1;
15715                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15716                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15717                        || procState > ActivityManager.PROCESS_STATE_TOP);
15718                provi--) {
15719            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15720            for (int i = cpr.connections.size()-1;
15721                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15722                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15723                            || procState > ActivityManager.PROCESS_STATE_TOP);
15724                    i--) {
15725                ContentProviderConnection conn = cpr.connections.get(i);
15726                ProcessRecord client = conn.client;
15727                if (client == app) {
15728                    // Being our own client is not interesting.
15729                    continue;
15730                }
15731                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15732                int clientProcState = client.curProcState;
15733                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15734                    // If the other app is cached for any reason, for purposes here
15735                    // we are going to consider it empty.
15736                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15737                }
15738                if (adj > clientAdj) {
15739                    if (app.hasShownUi && app != mHomeProcess
15740                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15741                        app.adjType = "cch-ui-provider";
15742                    } else {
15743                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15744                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15745                        app.adjType = "provider";
15746                    }
15747                    app.cached &= client.cached;
15748                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15749                            .REASON_PROVIDER_IN_USE;
15750                    app.adjSource = client;
15751                    app.adjSourceProcState = clientProcState;
15752                    app.adjTarget = cpr.name;
15753                }
15754                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15755                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15756                        // Special handling of clients who are in the top state.
15757                        // We *may* want to consider this process to be in the
15758                        // top state as well, but only if there is not another
15759                        // reason for it to be running.  Being on the top is a
15760                        // special state, meaning you are specifically running
15761                        // for the current top app.  If the process is already
15762                        // running in the background for some other reason, it
15763                        // is more important to continue considering it to be
15764                        // in the background state.
15765                        mayBeTop = true;
15766                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15767                    } else {
15768                        // Special handling for above-top states (persistent
15769                        // processes).  These should not bring the current process
15770                        // into the top state, since they are not on top.  Instead
15771                        // give them the best state after that.
15772                        clientProcState =
15773                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15774                    }
15775                }
15776                if (procState > clientProcState) {
15777                    procState = clientProcState;
15778                }
15779                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15780                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15781                }
15782            }
15783            // If the provider has external (non-framework) process
15784            // dependencies, ensure that its adjustment is at least
15785            // FOREGROUND_APP_ADJ.
15786            if (cpr.hasExternalProcessHandles()) {
15787                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15788                    adj = ProcessList.FOREGROUND_APP_ADJ;
15789                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15790                    app.cached = false;
15791                    app.adjType = "provider";
15792                    app.adjTarget = cpr.name;
15793                }
15794                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15795                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15796                }
15797            }
15798        }
15799
15800        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15801            // A client of one of our services or providers is in the top state.  We
15802            // *may* want to be in the top state, but not if we are already running in
15803            // the background for some other reason.  For the decision here, we are going
15804            // to pick out a few specific states that we want to remain in when a client
15805            // is top (states that tend to be longer-term) and otherwise allow it to go
15806            // to the top state.
15807            switch (procState) {
15808                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15809                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15810                case ActivityManager.PROCESS_STATE_SERVICE:
15811                    // These all are longer-term states, so pull them up to the top
15812                    // of the background states, but not all the way to the top state.
15813                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15814                    break;
15815                default:
15816                    // Otherwise, top is a better choice, so take it.
15817                    procState = ActivityManager.PROCESS_STATE_TOP;
15818                    break;
15819            }
15820        }
15821
15822        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15823            if (app.hasClientActivities) {
15824                // This is a cached process, but with client activities.  Mark it so.
15825                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15826                app.adjType = "cch-client-act";
15827            } else if (app.treatLikeActivity) {
15828                // This is a cached process, but somebody wants us to treat it like it has
15829                // an activity, okay!
15830                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15831                app.adjType = "cch-as-act";
15832            }
15833        }
15834
15835        if (adj == ProcessList.SERVICE_ADJ) {
15836            if (doingAll) {
15837                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15838                mNewNumServiceProcs++;
15839                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15840                if (!app.serviceb) {
15841                    // This service isn't far enough down on the LRU list to
15842                    // normally be a B service, but if we are low on RAM and it
15843                    // is large we want to force it down since we would prefer to
15844                    // keep launcher over it.
15845                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15846                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15847                        app.serviceHighRam = true;
15848                        app.serviceb = true;
15849                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15850                    } else {
15851                        mNewNumAServiceProcs++;
15852                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15853                    }
15854                } else {
15855                    app.serviceHighRam = false;
15856                }
15857            }
15858            if (app.serviceb) {
15859                adj = ProcessList.SERVICE_B_ADJ;
15860            }
15861        }
15862
15863        app.curRawAdj = adj;
15864
15865        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15866        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15867        if (adj > app.maxAdj) {
15868            adj = app.maxAdj;
15869            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15870                schedGroup = Process.THREAD_GROUP_DEFAULT;
15871            }
15872        }
15873
15874        // Do final modification to adj.  Everything we do between here and applying
15875        // the final setAdj must be done in this function, because we will also use
15876        // it when computing the final cached adj later.  Note that we don't need to
15877        // worry about this for max adj above, since max adj will always be used to
15878        // keep it out of the cached vaues.
15879        app.curAdj = app.modifyRawOomAdj(adj);
15880        app.curSchedGroup = schedGroup;
15881        app.curProcState = procState;
15882        app.foregroundActivities = foregroundActivities;
15883
15884        return app.curRawAdj;
15885    }
15886
15887    /**
15888     * Schedule PSS collection of a process.
15889     */
15890    void requestPssLocked(ProcessRecord proc, int procState) {
15891        if (mPendingPssProcesses.contains(proc)) {
15892            return;
15893        }
15894        if (mPendingPssProcesses.size() == 0) {
15895            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15896        }
15897        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15898        proc.pssProcState = procState;
15899        mPendingPssProcesses.add(proc);
15900    }
15901
15902    /**
15903     * Schedule PSS collection of all processes.
15904     */
15905    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15906        if (!always) {
15907            if (now < (mLastFullPssTime +
15908                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15909                return;
15910            }
15911        }
15912        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15913        mLastFullPssTime = now;
15914        mFullPssPending = true;
15915        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15916        mPendingPssProcesses.clear();
15917        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15918            ProcessRecord app = mLruProcesses.get(i);
15919            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15920                app.pssProcState = app.setProcState;
15921                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15922                        isSleeping(), now);
15923                mPendingPssProcesses.add(app);
15924            }
15925        }
15926        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15927    }
15928
15929    /**
15930     * Ask a given process to GC right now.
15931     */
15932    final void performAppGcLocked(ProcessRecord app) {
15933        try {
15934            app.lastRequestedGc = SystemClock.uptimeMillis();
15935            if (app.thread != null) {
15936                if (app.reportLowMemory) {
15937                    app.reportLowMemory = false;
15938                    app.thread.scheduleLowMemory();
15939                } else {
15940                    app.thread.processInBackground();
15941                }
15942            }
15943        } catch (Exception e) {
15944            // whatever.
15945        }
15946    }
15947
15948    /**
15949     * Returns true if things are idle enough to perform GCs.
15950     */
15951    private final boolean canGcNowLocked() {
15952        boolean processingBroadcasts = false;
15953        for (BroadcastQueue q : mBroadcastQueues) {
15954            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15955                processingBroadcasts = true;
15956            }
15957        }
15958        return !processingBroadcasts
15959                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15960    }
15961
15962    /**
15963     * Perform GCs on all processes that are waiting for it, but only
15964     * if things are idle.
15965     */
15966    final void performAppGcsLocked() {
15967        final int N = mProcessesToGc.size();
15968        if (N <= 0) {
15969            return;
15970        }
15971        if (canGcNowLocked()) {
15972            while (mProcessesToGc.size() > 0) {
15973                ProcessRecord proc = mProcessesToGc.remove(0);
15974                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15975                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15976                            <= SystemClock.uptimeMillis()) {
15977                        // To avoid spamming the system, we will GC processes one
15978                        // at a time, waiting a few seconds between each.
15979                        performAppGcLocked(proc);
15980                        scheduleAppGcsLocked();
15981                        return;
15982                    } else {
15983                        // It hasn't been long enough since we last GCed this
15984                        // process...  put it in the list to wait for its time.
15985                        addProcessToGcListLocked(proc);
15986                        break;
15987                    }
15988                }
15989            }
15990
15991            scheduleAppGcsLocked();
15992        }
15993    }
15994
15995    /**
15996     * If all looks good, perform GCs on all processes waiting for them.
15997     */
15998    final void performAppGcsIfAppropriateLocked() {
15999        if (canGcNowLocked()) {
16000            performAppGcsLocked();
16001            return;
16002        }
16003        // Still not idle, wait some more.
16004        scheduleAppGcsLocked();
16005    }
16006
16007    /**
16008     * Schedule the execution of all pending app GCs.
16009     */
16010    final void scheduleAppGcsLocked() {
16011        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16012
16013        if (mProcessesToGc.size() > 0) {
16014            // Schedule a GC for the time to the next process.
16015            ProcessRecord proc = mProcessesToGc.get(0);
16016            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16017
16018            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16019            long now = SystemClock.uptimeMillis();
16020            if (when < (now+GC_TIMEOUT)) {
16021                when = now + GC_TIMEOUT;
16022            }
16023            mHandler.sendMessageAtTime(msg, when);
16024        }
16025    }
16026
16027    /**
16028     * Add a process to the array of processes waiting to be GCed.  Keeps the
16029     * list in sorted order by the last GC time.  The process can't already be
16030     * on the list.
16031     */
16032    final void addProcessToGcListLocked(ProcessRecord proc) {
16033        boolean added = false;
16034        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16035            if (mProcessesToGc.get(i).lastRequestedGc <
16036                    proc.lastRequestedGc) {
16037                added = true;
16038                mProcessesToGc.add(i+1, proc);
16039                break;
16040            }
16041        }
16042        if (!added) {
16043            mProcessesToGc.add(0, proc);
16044        }
16045    }
16046
16047    /**
16048     * Set up to ask a process to GC itself.  This will either do it
16049     * immediately, or put it on the list of processes to gc the next
16050     * time things are idle.
16051     */
16052    final void scheduleAppGcLocked(ProcessRecord app) {
16053        long now = SystemClock.uptimeMillis();
16054        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16055            return;
16056        }
16057        if (!mProcessesToGc.contains(app)) {
16058            addProcessToGcListLocked(app);
16059            scheduleAppGcsLocked();
16060        }
16061    }
16062
16063    final void checkExcessivePowerUsageLocked(boolean doKills) {
16064        updateCpuStatsNow();
16065
16066        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16067        boolean doWakeKills = doKills;
16068        boolean doCpuKills = doKills;
16069        if (mLastPowerCheckRealtime == 0) {
16070            doWakeKills = false;
16071        }
16072        if (mLastPowerCheckUptime == 0) {
16073            doCpuKills = false;
16074        }
16075        if (stats.isScreenOn()) {
16076            doWakeKills = false;
16077        }
16078        final long curRealtime = SystemClock.elapsedRealtime();
16079        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16080        final long curUptime = SystemClock.uptimeMillis();
16081        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16082        mLastPowerCheckRealtime = curRealtime;
16083        mLastPowerCheckUptime = curUptime;
16084        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16085            doWakeKills = false;
16086        }
16087        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16088            doCpuKills = false;
16089        }
16090        int i = mLruProcesses.size();
16091        while (i > 0) {
16092            i--;
16093            ProcessRecord app = mLruProcesses.get(i);
16094            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16095                long wtime;
16096                synchronized (stats) {
16097                    wtime = stats.getProcessWakeTime(app.info.uid,
16098                            app.pid, curRealtime);
16099                }
16100                long wtimeUsed = wtime - app.lastWakeTime;
16101                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16102                if (DEBUG_POWER) {
16103                    StringBuilder sb = new StringBuilder(128);
16104                    sb.append("Wake for ");
16105                    app.toShortString(sb);
16106                    sb.append(": over ");
16107                    TimeUtils.formatDuration(realtimeSince, sb);
16108                    sb.append(" used ");
16109                    TimeUtils.formatDuration(wtimeUsed, sb);
16110                    sb.append(" (");
16111                    sb.append((wtimeUsed*100)/realtimeSince);
16112                    sb.append("%)");
16113                    Slog.i(TAG, sb.toString());
16114                    sb.setLength(0);
16115                    sb.append("CPU for ");
16116                    app.toShortString(sb);
16117                    sb.append(": over ");
16118                    TimeUtils.formatDuration(uptimeSince, sb);
16119                    sb.append(" used ");
16120                    TimeUtils.formatDuration(cputimeUsed, sb);
16121                    sb.append(" (");
16122                    sb.append((cputimeUsed*100)/uptimeSince);
16123                    sb.append("%)");
16124                    Slog.i(TAG, sb.toString());
16125                }
16126                // If a process has held a wake lock for more
16127                // than 50% of the time during this period,
16128                // that sounds bad.  Kill!
16129                if (doWakeKills && realtimeSince > 0
16130                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16131                    synchronized (stats) {
16132                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16133                                realtimeSince, wtimeUsed);
16134                    }
16135                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16136                            + " during " + realtimeSince);
16137                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16138                } else if (doCpuKills && uptimeSince > 0
16139                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16140                    synchronized (stats) {
16141                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16142                                uptimeSince, cputimeUsed);
16143                    }
16144                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16145                            + " during " + uptimeSince);
16146                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16147                } else {
16148                    app.lastWakeTime = wtime;
16149                    app.lastCpuTime = app.curCpuTime;
16150                }
16151            }
16152        }
16153    }
16154
16155    private final boolean applyOomAdjLocked(ProcessRecord app,
16156            ProcessRecord TOP_APP, boolean doingAll, long now) {
16157        boolean success = true;
16158
16159        if (app.curRawAdj != app.setRawAdj) {
16160            app.setRawAdj = app.curRawAdj;
16161        }
16162
16163        int changes = 0;
16164
16165        if (app.curAdj != app.setAdj) {
16166            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16167            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16168                TAG, "Set " + app.pid + " " + app.processName +
16169                " adj " + app.curAdj + ": " + app.adjType);
16170            app.setAdj = app.curAdj;
16171        }
16172
16173        if (app.setSchedGroup != app.curSchedGroup) {
16174            app.setSchedGroup = app.curSchedGroup;
16175            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16176                    "Setting process group of " + app.processName
16177                    + " to " + app.curSchedGroup);
16178            if (app.waitingToKill != null &&
16179                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16180                killUnneededProcessLocked(app, app.waitingToKill);
16181                success = false;
16182            } else {
16183                if (true) {
16184                    long oldId = Binder.clearCallingIdentity();
16185                    try {
16186                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16187                    } catch (Exception e) {
16188                        Slog.w(TAG, "Failed setting process group of " + app.pid
16189                                + " to " + app.curSchedGroup);
16190                        e.printStackTrace();
16191                    } finally {
16192                        Binder.restoreCallingIdentity(oldId);
16193                    }
16194                } else {
16195                    if (app.thread != null) {
16196                        try {
16197                            app.thread.setSchedulingGroup(app.curSchedGroup);
16198                        } catch (RemoteException e) {
16199                        }
16200                    }
16201                }
16202                Process.setSwappiness(app.pid,
16203                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16204            }
16205        }
16206        if (app.repForegroundActivities != app.foregroundActivities) {
16207            app.repForegroundActivities = app.foregroundActivities;
16208            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16209        }
16210        if (app.repProcState != app.curProcState) {
16211            app.repProcState = app.curProcState;
16212            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16213            if (app.thread != null) {
16214                try {
16215                    if (false) {
16216                        //RuntimeException h = new RuntimeException("here");
16217                        Slog.i(TAG, "Sending new process state " + app.repProcState
16218                                + " to " + app /*, h*/);
16219                    }
16220                    app.thread.setProcessState(app.repProcState);
16221                } catch (RemoteException e) {
16222                }
16223            }
16224        }
16225        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16226                app.setProcState)) {
16227            app.lastStateTime = now;
16228            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16229                    isSleeping(), now);
16230            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16231                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16232                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16233                    + (app.nextPssTime-now) + ": " + app);
16234        } else {
16235            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16236                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16237                requestPssLocked(app, app.setProcState);
16238                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16239                        isSleeping(), now);
16240            } else if (false && DEBUG_PSS) {
16241                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16242            }
16243        }
16244        if (app.setProcState != app.curProcState) {
16245            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16246                    "Proc state change of " + app.processName
16247                    + " to " + app.curProcState);
16248            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16249            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16250            if (setImportant && !curImportant) {
16251                // This app is no longer something we consider important enough to allow to
16252                // use arbitrary amounts of battery power.  Note
16253                // its current wake lock time to later know to kill it if
16254                // it is not behaving well.
16255                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16256                synchronized (stats) {
16257                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16258                            app.pid, SystemClock.elapsedRealtime());
16259                }
16260                app.lastCpuTime = app.curCpuTime;
16261
16262            }
16263            app.setProcState = app.curProcState;
16264            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16265                app.notCachedSinceIdle = false;
16266            }
16267            if (!doingAll) {
16268                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16269            } else {
16270                app.procStateChanged = true;
16271            }
16272        }
16273
16274        if (changes != 0) {
16275            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16276            int i = mPendingProcessChanges.size()-1;
16277            ProcessChangeItem item = null;
16278            while (i >= 0) {
16279                item = mPendingProcessChanges.get(i);
16280                if (item.pid == app.pid) {
16281                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16282                    break;
16283                }
16284                i--;
16285            }
16286            if (i < 0) {
16287                // No existing item in pending changes; need a new one.
16288                final int NA = mAvailProcessChanges.size();
16289                if (NA > 0) {
16290                    item = mAvailProcessChanges.remove(NA-1);
16291                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16292                } else {
16293                    item = new ProcessChangeItem();
16294                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16295                }
16296                item.changes = 0;
16297                item.pid = app.pid;
16298                item.uid = app.info.uid;
16299                if (mPendingProcessChanges.size() == 0) {
16300                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16301                            "*** Enqueueing dispatch processes changed!");
16302                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16303                }
16304                mPendingProcessChanges.add(item);
16305            }
16306            item.changes |= changes;
16307            item.processState = app.repProcState;
16308            item.foregroundActivities = app.repForegroundActivities;
16309            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16310                    + Integer.toHexString(System.identityHashCode(item))
16311                    + " " + app.toShortString() + ": changes=" + item.changes
16312                    + " procState=" + item.processState
16313                    + " foreground=" + item.foregroundActivities
16314                    + " type=" + app.adjType + " source=" + app.adjSource
16315                    + " target=" + app.adjTarget);
16316        }
16317
16318        return success;
16319    }
16320
16321    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16322        if (proc.thread != null) {
16323            if (proc.baseProcessTracker != null) {
16324                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16325            }
16326            if (proc.repProcState >= 0) {
16327                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16328                        proc.repProcState);
16329            }
16330        }
16331    }
16332
16333    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16334            ProcessRecord TOP_APP, boolean doingAll, long now) {
16335        if (app.thread == null) {
16336            return false;
16337        }
16338
16339        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16340
16341        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16342    }
16343
16344    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16345            boolean oomAdj) {
16346        if (isForeground != proc.foregroundServices) {
16347            proc.foregroundServices = isForeground;
16348            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16349                    proc.info.uid);
16350            if (isForeground) {
16351                if (curProcs == null) {
16352                    curProcs = new ArrayList<ProcessRecord>();
16353                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16354                }
16355                if (!curProcs.contains(proc)) {
16356                    curProcs.add(proc);
16357                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16358                            proc.info.packageName, proc.info.uid);
16359                }
16360            } else {
16361                if (curProcs != null) {
16362                    if (curProcs.remove(proc)) {
16363                        mBatteryStatsService.noteEvent(
16364                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16365                                proc.info.packageName, proc.info.uid);
16366                        if (curProcs.size() <= 0) {
16367                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16368                        }
16369                    }
16370                }
16371            }
16372            if (oomAdj) {
16373                updateOomAdjLocked();
16374            }
16375        }
16376    }
16377
16378    private final ActivityRecord resumedAppLocked() {
16379        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16380        String pkg;
16381        int uid;
16382        if (act != null) {
16383            pkg = act.packageName;
16384            uid = act.info.applicationInfo.uid;
16385        } else {
16386            pkg = null;
16387            uid = -1;
16388        }
16389        // Has the UID or resumed package name changed?
16390        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16391                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16392            if (mCurResumedPackage != null) {
16393                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16394                        mCurResumedPackage, mCurResumedUid);
16395            }
16396            mCurResumedPackage = pkg;
16397            mCurResumedUid = uid;
16398            if (mCurResumedPackage != null) {
16399                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16400                        mCurResumedPackage, mCurResumedUid);
16401            }
16402        }
16403        return act;
16404    }
16405
16406    final boolean updateOomAdjLocked(ProcessRecord app) {
16407        final ActivityRecord TOP_ACT = resumedAppLocked();
16408        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16409        final boolean wasCached = app.cached;
16410
16411        mAdjSeq++;
16412
16413        // This is the desired cached adjusment we want to tell it to use.
16414        // If our app is currently cached, we know it, and that is it.  Otherwise,
16415        // we don't know it yet, and it needs to now be cached we will then
16416        // need to do a complete oom adj.
16417        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16418                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16419        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16420                SystemClock.uptimeMillis());
16421        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16422            // Changed to/from cached state, so apps after it in the LRU
16423            // list may also be changed.
16424            updateOomAdjLocked();
16425        }
16426        return success;
16427    }
16428
16429    final void updateOomAdjLocked() {
16430        final ActivityRecord TOP_ACT = resumedAppLocked();
16431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16432        final long now = SystemClock.uptimeMillis();
16433        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16434        final int N = mLruProcesses.size();
16435
16436        if (false) {
16437            RuntimeException e = new RuntimeException();
16438            e.fillInStackTrace();
16439            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16440        }
16441
16442        mAdjSeq++;
16443        mNewNumServiceProcs = 0;
16444        mNewNumAServiceProcs = 0;
16445
16446        final int emptyProcessLimit;
16447        final int cachedProcessLimit;
16448        if (mProcessLimit <= 0) {
16449            emptyProcessLimit = cachedProcessLimit = 0;
16450        } else if (mProcessLimit == 1) {
16451            emptyProcessLimit = 1;
16452            cachedProcessLimit = 0;
16453        } else {
16454            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16455            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16456        }
16457
16458        // Let's determine how many processes we have running vs.
16459        // how many slots we have for background processes; we may want
16460        // to put multiple processes in a slot of there are enough of
16461        // them.
16462        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16463                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16464        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16465        if (numEmptyProcs > cachedProcessLimit) {
16466            // If there are more empty processes than our limit on cached
16467            // processes, then use the cached process limit for the factor.
16468            // This ensures that the really old empty processes get pushed
16469            // down to the bottom, so if we are running low on memory we will
16470            // have a better chance at keeping around more cached processes
16471            // instead of a gazillion empty processes.
16472            numEmptyProcs = cachedProcessLimit;
16473        }
16474        int emptyFactor = numEmptyProcs/numSlots;
16475        if (emptyFactor < 1) emptyFactor = 1;
16476        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16477        if (cachedFactor < 1) cachedFactor = 1;
16478        int stepCached = 0;
16479        int stepEmpty = 0;
16480        int numCached = 0;
16481        int numEmpty = 0;
16482        int numTrimming = 0;
16483
16484        mNumNonCachedProcs = 0;
16485        mNumCachedHiddenProcs = 0;
16486
16487        // First update the OOM adjustment for each of the
16488        // application processes based on their current state.
16489        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16490        int nextCachedAdj = curCachedAdj+1;
16491        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16492        int nextEmptyAdj = curEmptyAdj+2;
16493        for (int i=N-1; i>=0; i--) {
16494            ProcessRecord app = mLruProcesses.get(i);
16495            if (!app.killedByAm && app.thread != null) {
16496                app.procStateChanged = false;
16497                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16498
16499                // If we haven't yet assigned the final cached adj
16500                // to the process, do that now.
16501                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16502                    switch (app.curProcState) {
16503                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16504                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16505                            // This process is a cached process holding activities...
16506                            // assign it the next cached value for that type, and then
16507                            // step that cached level.
16508                            app.curRawAdj = curCachedAdj;
16509                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16510                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16511                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16512                                    + ")");
16513                            if (curCachedAdj != nextCachedAdj) {
16514                                stepCached++;
16515                                if (stepCached >= cachedFactor) {
16516                                    stepCached = 0;
16517                                    curCachedAdj = nextCachedAdj;
16518                                    nextCachedAdj += 2;
16519                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16520                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16521                                    }
16522                                }
16523                            }
16524                            break;
16525                        default:
16526                            // For everything else, assign next empty cached process
16527                            // level and bump that up.  Note that this means that
16528                            // long-running services that have dropped down to the
16529                            // cached level will be treated as empty (since their process
16530                            // state is still as a service), which is what we want.
16531                            app.curRawAdj = curEmptyAdj;
16532                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16533                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16534                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16535                                    + ")");
16536                            if (curEmptyAdj != nextEmptyAdj) {
16537                                stepEmpty++;
16538                                if (stepEmpty >= emptyFactor) {
16539                                    stepEmpty = 0;
16540                                    curEmptyAdj = nextEmptyAdj;
16541                                    nextEmptyAdj += 2;
16542                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16543                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16544                                    }
16545                                }
16546                            }
16547                            break;
16548                    }
16549                }
16550
16551                applyOomAdjLocked(app, TOP_APP, true, now);
16552
16553                // Count the number of process types.
16554                switch (app.curProcState) {
16555                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16556                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16557                        mNumCachedHiddenProcs++;
16558                        numCached++;
16559                        if (numCached > cachedProcessLimit) {
16560                            killUnneededProcessLocked(app, "cached #" + numCached);
16561                        }
16562                        break;
16563                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16564                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16565                                && app.lastActivityTime < oldTime) {
16566                            killUnneededProcessLocked(app, "empty for "
16567                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16568                                    / 1000) + "s");
16569                        } else {
16570                            numEmpty++;
16571                            if (numEmpty > emptyProcessLimit) {
16572                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16573                            }
16574                        }
16575                        break;
16576                    default:
16577                        mNumNonCachedProcs++;
16578                        break;
16579                }
16580
16581                if (app.isolated && app.services.size() <= 0) {
16582                    // If this is an isolated process, and there are no
16583                    // services running in it, then the process is no longer
16584                    // needed.  We agressively kill these because we can by
16585                    // definition not re-use the same process again, and it is
16586                    // good to avoid having whatever code was running in them
16587                    // left sitting around after no longer needed.
16588                    killUnneededProcessLocked(app, "isolated not needed");
16589                }
16590
16591                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16592                        && !app.killedByAm) {
16593                    numTrimming++;
16594                }
16595            }
16596        }
16597
16598        mNumServiceProcs = mNewNumServiceProcs;
16599
16600        // Now determine the memory trimming level of background processes.
16601        // Unfortunately we need to start at the back of the list to do this
16602        // properly.  We only do this if the number of background apps we
16603        // are managing to keep around is less than half the maximum we desire;
16604        // if we are keeping a good number around, we'll let them use whatever
16605        // memory they want.
16606        final int numCachedAndEmpty = numCached + numEmpty;
16607        int memFactor;
16608        if (numCached <= ProcessList.TRIM_CACHED_APPS
16609                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16610            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16611                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16612            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16613                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16614            } else {
16615                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16616            }
16617        } else {
16618            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16619        }
16620        // We always allow the memory level to go up (better).  We only allow it to go
16621        // down if we are in a state where that is allowed, *and* the total number of processes
16622        // has gone down since last time.
16623        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16624                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16625                + " last=" + mLastNumProcesses);
16626        if (memFactor > mLastMemoryLevel) {
16627            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16628                memFactor = mLastMemoryLevel;
16629                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16630            }
16631        }
16632        mLastMemoryLevel = memFactor;
16633        mLastNumProcesses = mLruProcesses.size();
16634        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16635        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16636        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16637            if (mLowRamStartTime == 0) {
16638                mLowRamStartTime = now;
16639            }
16640            int step = 0;
16641            int fgTrimLevel;
16642            switch (memFactor) {
16643                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16644                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16645                    break;
16646                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16647                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16648                    break;
16649                default:
16650                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16651                    break;
16652            }
16653            int factor = numTrimming/3;
16654            int minFactor = 2;
16655            if (mHomeProcess != null) minFactor++;
16656            if (mPreviousProcess != null) minFactor++;
16657            if (factor < minFactor) factor = minFactor;
16658            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16659            for (int i=N-1; i>=0; i--) {
16660                ProcessRecord app = mLruProcesses.get(i);
16661                if (allChanged || app.procStateChanged) {
16662                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16663                    app.procStateChanged = false;
16664                }
16665                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16666                        && !app.killedByAm) {
16667                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16668                        try {
16669                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16670                                    "Trimming memory of " + app.processName
16671                                    + " to " + curLevel);
16672                            app.thread.scheduleTrimMemory(curLevel);
16673                        } catch (RemoteException e) {
16674                        }
16675                        if (false) {
16676                            // For now we won't do this; our memory trimming seems
16677                            // to be good enough at this point that destroying
16678                            // activities causes more harm than good.
16679                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16680                                    && app != mHomeProcess && app != mPreviousProcess) {
16681                                // Need to do this on its own message because the stack may not
16682                                // be in a consistent state at this point.
16683                                // For these apps we will also finish their activities
16684                                // to help them free memory.
16685                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16686                            }
16687                        }
16688                    }
16689                    app.trimMemoryLevel = curLevel;
16690                    step++;
16691                    if (step >= factor) {
16692                        step = 0;
16693                        switch (curLevel) {
16694                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16695                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16696                                break;
16697                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16698                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16699                                break;
16700                        }
16701                    }
16702                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16703                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16704                            && app.thread != null) {
16705                        try {
16706                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16707                                    "Trimming memory of heavy-weight " + app.processName
16708                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16709                            app.thread.scheduleTrimMemory(
16710                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16711                        } catch (RemoteException e) {
16712                        }
16713                    }
16714                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16715                } else {
16716                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16717                            || app.systemNoUi) && app.pendingUiClean) {
16718                        // If this application is now in the background and it
16719                        // had done UI, then give it the special trim level to
16720                        // have it free UI resources.
16721                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16722                        if (app.trimMemoryLevel < level && app.thread != null) {
16723                            try {
16724                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16725                                        "Trimming memory of bg-ui " + app.processName
16726                                        + " to " + level);
16727                                app.thread.scheduleTrimMemory(level);
16728                            } catch (RemoteException e) {
16729                            }
16730                        }
16731                        app.pendingUiClean = false;
16732                    }
16733                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16734                        try {
16735                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16736                                    "Trimming memory of fg " + app.processName
16737                                    + " to " + fgTrimLevel);
16738                            app.thread.scheduleTrimMemory(fgTrimLevel);
16739                        } catch (RemoteException e) {
16740                        }
16741                    }
16742                    app.trimMemoryLevel = fgTrimLevel;
16743                }
16744            }
16745        } else {
16746            if (mLowRamStartTime != 0) {
16747                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16748                mLowRamStartTime = 0;
16749            }
16750            for (int i=N-1; i>=0; i--) {
16751                ProcessRecord app = mLruProcesses.get(i);
16752                if (allChanged || app.procStateChanged) {
16753                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16754                    app.procStateChanged = false;
16755                }
16756                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16757                        || app.systemNoUi) && app.pendingUiClean) {
16758                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16759                            && app.thread != null) {
16760                        try {
16761                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16762                                    "Trimming memory of ui hidden " + app.processName
16763                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16764                            app.thread.scheduleTrimMemory(
16765                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16766                        } catch (RemoteException e) {
16767                        }
16768                    }
16769                    app.pendingUiClean = false;
16770                }
16771                app.trimMemoryLevel = 0;
16772            }
16773        }
16774
16775        if (mAlwaysFinishActivities) {
16776            // Need to do this on its own message because the stack may not
16777            // be in a consistent state at this point.
16778            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16779        }
16780
16781        if (allChanged) {
16782            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16783        }
16784
16785        if (mProcessStats.shouldWriteNowLocked(now)) {
16786            mHandler.post(new Runnable() {
16787                @Override public void run() {
16788                    synchronized (ActivityManagerService.this) {
16789                        mProcessStats.writeStateAsyncLocked();
16790                    }
16791                }
16792            });
16793        }
16794
16795        if (DEBUG_OOM_ADJ) {
16796            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16797        }
16798    }
16799
16800    final void trimApplications() {
16801        synchronized (this) {
16802            int i;
16803
16804            // First remove any unused application processes whose package
16805            // has been removed.
16806            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16807                final ProcessRecord app = mRemovedProcesses.get(i);
16808                if (app.activities.size() == 0
16809                        && app.curReceiver == null && app.services.size() == 0) {
16810                    Slog.i(
16811                        TAG, "Exiting empty application process "
16812                        + app.processName + " ("
16813                        + (app.thread != null ? app.thread.asBinder() : null)
16814                        + ")\n");
16815                    if (app.pid > 0 && app.pid != MY_PID) {
16816                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16817                                app.processName, app.setAdj, "empty");
16818                        app.killedByAm = true;
16819                        Process.killProcessQuiet(app.pid);
16820                        Process.killProcessGroup(app.info.uid, app.pid);
16821                    } else {
16822                        try {
16823                            app.thread.scheduleExit();
16824                        } catch (Exception e) {
16825                            // Ignore exceptions.
16826                        }
16827                    }
16828                    cleanUpApplicationRecordLocked(app, false, true, -1);
16829                    mRemovedProcesses.remove(i);
16830
16831                    if (app.persistent) {
16832                        addAppLocked(app.info, false, null /* ABI override */);
16833                    }
16834                }
16835            }
16836
16837            // Now update the oom adj for all processes.
16838            updateOomAdjLocked();
16839        }
16840    }
16841
16842    /** This method sends the specified signal to each of the persistent apps */
16843    public void signalPersistentProcesses(int sig) throws RemoteException {
16844        if (sig != Process.SIGNAL_USR1) {
16845            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16846        }
16847
16848        synchronized (this) {
16849            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16850                    != PackageManager.PERMISSION_GRANTED) {
16851                throw new SecurityException("Requires permission "
16852                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16853            }
16854
16855            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16856                ProcessRecord r = mLruProcesses.get(i);
16857                if (r.thread != null && r.persistent) {
16858                    Process.sendSignal(r.pid, sig);
16859                }
16860            }
16861        }
16862    }
16863
16864    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16865        if (proc == null || proc == mProfileProc) {
16866            proc = mProfileProc;
16867            path = mProfileFile;
16868            profileType = mProfileType;
16869            clearProfilerLocked();
16870        }
16871        if (proc == null) {
16872            return;
16873        }
16874        try {
16875            proc.thread.profilerControl(false, path, null, profileType);
16876        } catch (RemoteException e) {
16877            throw new IllegalStateException("Process disappeared");
16878        }
16879    }
16880
16881    private void clearProfilerLocked() {
16882        if (mProfileFd != null) {
16883            try {
16884                mProfileFd.close();
16885            } catch (IOException e) {
16886            }
16887        }
16888        mProfileApp = null;
16889        mProfileProc = null;
16890        mProfileFile = null;
16891        mProfileType = 0;
16892        mAutoStopProfiler = false;
16893    }
16894
16895    public boolean profileControl(String process, int userId, boolean start,
16896            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16897
16898        try {
16899            synchronized (this) {
16900                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16901                // its own permission.
16902                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16903                        != PackageManager.PERMISSION_GRANTED) {
16904                    throw new SecurityException("Requires permission "
16905                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16906                }
16907
16908                if (start && fd == null) {
16909                    throw new IllegalArgumentException("null fd");
16910                }
16911
16912                ProcessRecord proc = null;
16913                if (process != null) {
16914                    proc = findProcessLocked(process, userId, "profileControl");
16915                }
16916
16917                if (start && (proc == null || proc.thread == null)) {
16918                    throw new IllegalArgumentException("Unknown process: " + process);
16919                }
16920
16921                if (start) {
16922                    stopProfilerLocked(null, null, 0);
16923                    setProfileApp(proc.info, proc.processName, path, fd, false);
16924                    mProfileProc = proc;
16925                    mProfileType = profileType;
16926                    try {
16927                        fd = fd.dup();
16928                    } catch (IOException e) {
16929                        fd = null;
16930                    }
16931                    proc.thread.profilerControl(start, path, fd, profileType);
16932                    fd = null;
16933                    mProfileFd = null;
16934                } else {
16935                    stopProfilerLocked(proc, path, profileType);
16936                    if (fd != null) {
16937                        try {
16938                            fd.close();
16939                        } catch (IOException e) {
16940                        }
16941                    }
16942                }
16943
16944                return true;
16945            }
16946        } catch (RemoteException e) {
16947            throw new IllegalStateException("Process disappeared");
16948        } finally {
16949            if (fd != null) {
16950                try {
16951                    fd.close();
16952                } catch (IOException e) {
16953                }
16954            }
16955        }
16956    }
16957
16958    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16959        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16960                userId, true, ALLOW_FULL_ONLY, callName, null);
16961        ProcessRecord proc = null;
16962        try {
16963            int pid = Integer.parseInt(process);
16964            synchronized (mPidsSelfLocked) {
16965                proc = mPidsSelfLocked.get(pid);
16966            }
16967        } catch (NumberFormatException e) {
16968        }
16969
16970        if (proc == null) {
16971            ArrayMap<String, SparseArray<ProcessRecord>> all
16972                    = mProcessNames.getMap();
16973            SparseArray<ProcessRecord> procs = all.get(process);
16974            if (procs != null && procs.size() > 0) {
16975                proc = procs.valueAt(0);
16976                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16977                    for (int i=1; i<procs.size(); i++) {
16978                        ProcessRecord thisProc = procs.valueAt(i);
16979                        if (thisProc.userId == userId) {
16980                            proc = thisProc;
16981                            break;
16982                        }
16983                    }
16984                }
16985            }
16986        }
16987
16988        return proc;
16989    }
16990
16991    public boolean dumpHeap(String process, int userId, boolean managed,
16992            String path, ParcelFileDescriptor fd) throws RemoteException {
16993
16994        try {
16995            synchronized (this) {
16996                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16997                // its own permission (same as profileControl).
16998                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16999                        != PackageManager.PERMISSION_GRANTED) {
17000                    throw new SecurityException("Requires permission "
17001                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17002                }
17003
17004                if (fd == null) {
17005                    throw new IllegalArgumentException("null fd");
17006                }
17007
17008                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17009                if (proc == null || proc.thread == null) {
17010                    throw new IllegalArgumentException("Unknown process: " + process);
17011                }
17012
17013                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17014                if (!isDebuggable) {
17015                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17016                        throw new SecurityException("Process not debuggable: " + proc);
17017                    }
17018                }
17019
17020                proc.thread.dumpHeap(managed, path, fd);
17021                fd = null;
17022                return true;
17023            }
17024        } catch (RemoteException e) {
17025            throw new IllegalStateException("Process disappeared");
17026        } finally {
17027            if (fd != null) {
17028                try {
17029                    fd.close();
17030                } catch (IOException e) {
17031                }
17032            }
17033        }
17034    }
17035
17036    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17037    public void monitor() {
17038        synchronized (this) { }
17039    }
17040
17041    void onCoreSettingsChange(Bundle settings) {
17042        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17043            ProcessRecord processRecord = mLruProcesses.get(i);
17044            try {
17045                if (processRecord.thread != null) {
17046                    processRecord.thread.setCoreSettings(settings);
17047                }
17048            } catch (RemoteException re) {
17049                /* ignore */
17050            }
17051        }
17052    }
17053
17054    // Multi-user methods
17055
17056    /**
17057     * Start user, if its not already running, but don't bring it to foreground.
17058     */
17059    @Override
17060    public boolean startUserInBackground(final int userId) {
17061        return startUser(userId, /* foreground */ false);
17062    }
17063
17064    /**
17065     * Refreshes the list of users related to the current user when either a
17066     * user switch happens or when a new related user is started in the
17067     * background.
17068     */
17069    private void updateCurrentProfileIdsLocked() {
17070        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17071                mCurrentUserId, false /* enabledOnly */);
17072        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17073        for (int i = 0; i < currentProfileIds.length; i++) {
17074            currentProfileIds[i] = profiles.get(i).id;
17075        }
17076        mCurrentProfileIds = currentProfileIds;
17077
17078        synchronized (mUserProfileGroupIdsSelfLocked) {
17079            mUserProfileGroupIdsSelfLocked.clear();
17080            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17081            for (int i = 0; i < users.size(); i++) {
17082                UserInfo user = users.get(i);
17083                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17084                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17085                }
17086            }
17087        }
17088    }
17089
17090    private Set getProfileIdsLocked(int userId) {
17091        Set userIds = new HashSet<Integer>();
17092        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17093                userId, false /* enabledOnly */);
17094        for (UserInfo user : profiles) {
17095            userIds.add(Integer.valueOf(user.id));
17096        }
17097        return userIds;
17098    }
17099
17100    @Override
17101    public boolean switchUser(final int userId) {
17102        return startUser(userId, /* foregound */ true);
17103    }
17104
17105    private boolean startUser(final int userId, boolean foreground) {
17106        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17107                != PackageManager.PERMISSION_GRANTED) {
17108            String msg = "Permission Denial: switchUser() from pid="
17109                    + Binder.getCallingPid()
17110                    + ", uid=" + Binder.getCallingUid()
17111                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17112            Slog.w(TAG, msg);
17113            throw new SecurityException(msg);
17114        }
17115
17116        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17117
17118        final long ident = Binder.clearCallingIdentity();
17119        try {
17120            synchronized (this) {
17121                final int oldUserId = mCurrentUserId;
17122                if (oldUserId == userId) {
17123                    return true;
17124                }
17125
17126                mStackSupervisor.setLockTaskModeLocked(null, false);
17127
17128                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17129                if (userInfo == null) {
17130                    Slog.w(TAG, "No user info for user #" + userId);
17131                    return false;
17132                }
17133
17134                if (foreground) {
17135                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17136                            R.anim.screen_user_enter);
17137                }
17138
17139                boolean needStart = false;
17140
17141                // If the user we are switching to is not currently started, then
17142                // we need to start it now.
17143                if (mStartedUsers.get(userId) == null) {
17144                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17145                    updateStartedUserArrayLocked();
17146                    needStart = true;
17147                }
17148
17149                final Integer userIdInt = Integer.valueOf(userId);
17150                mUserLru.remove(userIdInt);
17151                mUserLru.add(userIdInt);
17152
17153                if (foreground) {
17154                    mCurrentUserId = userId;
17155                    updateCurrentProfileIdsLocked();
17156                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17157                    // Once the internal notion of the active user has switched, we lock the device
17158                    // with the option to show the user switcher on the keyguard.
17159                    mWindowManager.lockNow(null);
17160                } else {
17161                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17162                    updateCurrentProfileIdsLocked();
17163                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17164                    mUserLru.remove(currentUserIdInt);
17165                    mUserLru.add(currentUserIdInt);
17166                }
17167
17168                final UserStartedState uss = mStartedUsers.get(userId);
17169
17170                // Make sure user is in the started state.  If it is currently
17171                // stopping, we need to knock that off.
17172                if (uss.mState == UserStartedState.STATE_STOPPING) {
17173                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17174                    // so we can just fairly silently bring the user back from
17175                    // the almost-dead.
17176                    uss.mState = UserStartedState.STATE_RUNNING;
17177                    updateStartedUserArrayLocked();
17178                    needStart = true;
17179                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17180                    // This means ACTION_SHUTDOWN has been sent, so we will
17181                    // need to treat this as a new boot of the user.
17182                    uss.mState = UserStartedState.STATE_BOOTING;
17183                    updateStartedUserArrayLocked();
17184                    needStart = true;
17185                }
17186
17187                if (uss.mState == UserStartedState.STATE_BOOTING) {
17188                    // Booting up a new user, need to tell system services about it.
17189                    // Note that this is on the same handler as scheduling of broadcasts,
17190                    // which is important because it needs to go first.
17191                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17192                }
17193
17194                if (foreground) {
17195                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17196                            oldUserId));
17197                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17198                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17199                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17200                            oldUserId, userId, uss));
17201                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17202                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17203                }
17204
17205                if (needStart) {
17206                    // Send USER_STARTED broadcast
17207                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17208                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17209                            | Intent.FLAG_RECEIVER_FOREGROUND);
17210                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17211                    broadcastIntentLocked(null, null, intent,
17212                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17213                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17214                }
17215
17216                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17217                    if (userId != UserHandle.USER_OWNER) {
17218                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17219                        final ArrayList<ComponentName> doneReceivers
17220                                = new ArrayList<ComponentName>();
17221                        deliverPreBootCompleted(null, doneReceivers, userId);
17222
17223                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17224                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17225                        broadcastIntentLocked(null, null, intent, null,
17226                                new IIntentReceiver.Stub() {
17227                                    public void performReceive(Intent intent, int resultCode,
17228                                            String data, Bundle extras, boolean ordered,
17229                                            boolean sticky, int sendingUser) {
17230                                        userInitialized(uss, userId);
17231                                    }
17232                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17233                                true, false, MY_PID, Process.SYSTEM_UID,
17234                                userId);
17235                        uss.initializing = true;
17236                    } else {
17237                        getUserManagerLocked().makeInitialized(userInfo.id);
17238                    }
17239                }
17240
17241                if (foreground) {
17242                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17243                    if (homeInFront) {
17244                        startHomeActivityLocked(userId);
17245                    } else {
17246                        mStackSupervisor.resumeTopActivitiesLocked();
17247                    }
17248                    EventLogTags.writeAmSwitchUser(userId);
17249                    getUserManagerLocked().userForeground(userId);
17250                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17251                } else {
17252                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17253                }
17254
17255                if (needStart) {
17256                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17257                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17258                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17259                    broadcastIntentLocked(null, null, intent,
17260                            null, new IIntentReceiver.Stub() {
17261                                @Override
17262                                public void performReceive(Intent intent, int resultCode, String data,
17263                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17264                                        throws RemoteException {
17265                                }
17266                            }, 0, null, null,
17267                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17268                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17269                }
17270            }
17271        } finally {
17272            Binder.restoreCallingIdentity(ident);
17273        }
17274
17275        return true;
17276    }
17277
17278    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17279        long ident = Binder.clearCallingIdentity();
17280        try {
17281            Intent intent;
17282            if (oldUserId >= 0) {
17283                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17284                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17285                int count = profiles.size();
17286                for (int i = 0; i < count; i++) {
17287                    int profileUserId = profiles.get(i).id;
17288                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17289                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17290                            | Intent.FLAG_RECEIVER_FOREGROUND);
17291                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17292                    broadcastIntentLocked(null, null, intent,
17293                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17294                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17295                }
17296            }
17297            if (newUserId >= 0) {
17298                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17299                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17300                int count = profiles.size();
17301                for (int i = 0; i < count; i++) {
17302                    int profileUserId = profiles.get(i).id;
17303                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17304                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17305                            | Intent.FLAG_RECEIVER_FOREGROUND);
17306                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17307                    broadcastIntentLocked(null, null, intent,
17308                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17309                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17310                }
17311                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17312                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17313                        | Intent.FLAG_RECEIVER_FOREGROUND);
17314                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17315                broadcastIntentLocked(null, null, intent,
17316                        null, null, 0, null, null,
17317                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17318                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17319            }
17320        } finally {
17321            Binder.restoreCallingIdentity(ident);
17322        }
17323    }
17324
17325    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17326            final int newUserId) {
17327        final int N = mUserSwitchObservers.beginBroadcast();
17328        if (N > 0) {
17329            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17330                int mCount = 0;
17331                @Override
17332                public void sendResult(Bundle data) throws RemoteException {
17333                    synchronized (ActivityManagerService.this) {
17334                        if (mCurUserSwitchCallback == this) {
17335                            mCount++;
17336                            if (mCount == N) {
17337                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17338                            }
17339                        }
17340                    }
17341                }
17342            };
17343            synchronized (this) {
17344                uss.switching = true;
17345                mCurUserSwitchCallback = callback;
17346            }
17347            for (int i=0; i<N; i++) {
17348                try {
17349                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17350                            newUserId, callback);
17351                } catch (RemoteException e) {
17352                }
17353            }
17354        } else {
17355            synchronized (this) {
17356                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17357            }
17358        }
17359        mUserSwitchObservers.finishBroadcast();
17360    }
17361
17362    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17363        synchronized (this) {
17364            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17365            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17366        }
17367    }
17368
17369    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17370        mCurUserSwitchCallback = null;
17371        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17372        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17373                oldUserId, newUserId, uss));
17374    }
17375
17376    void userInitialized(UserStartedState uss, int newUserId) {
17377        completeSwitchAndInitalize(uss, newUserId, true, false);
17378    }
17379
17380    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17381        completeSwitchAndInitalize(uss, newUserId, false, true);
17382    }
17383
17384    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17385            boolean clearInitializing, boolean clearSwitching) {
17386        boolean unfrozen = false;
17387        synchronized (this) {
17388            if (clearInitializing) {
17389                uss.initializing = false;
17390                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17391            }
17392            if (clearSwitching) {
17393                uss.switching = false;
17394            }
17395            if (!uss.switching && !uss.initializing) {
17396                mWindowManager.stopFreezingScreen();
17397                unfrozen = true;
17398            }
17399        }
17400        if (unfrozen) {
17401            final int N = mUserSwitchObservers.beginBroadcast();
17402            for (int i=0; i<N; i++) {
17403                try {
17404                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17405                } catch (RemoteException e) {
17406                }
17407            }
17408            mUserSwitchObservers.finishBroadcast();
17409        }
17410    }
17411
17412    void scheduleStartProfilesLocked() {
17413        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17414            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17415                    DateUtils.SECOND_IN_MILLIS);
17416        }
17417    }
17418
17419    void startProfilesLocked() {
17420        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17421        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17422                mCurrentUserId, false /* enabledOnly */);
17423        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17424        for (UserInfo user : profiles) {
17425            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17426                    && user.id != mCurrentUserId) {
17427                toStart.add(user);
17428            }
17429        }
17430        final int n = toStart.size();
17431        int i = 0;
17432        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17433            startUserInBackground(toStart.get(i).id);
17434        }
17435        if (i < n) {
17436            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17437        }
17438    }
17439
17440    void finishUserBoot(UserStartedState uss) {
17441        synchronized (this) {
17442            if (uss.mState == UserStartedState.STATE_BOOTING
17443                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17444                uss.mState = UserStartedState.STATE_RUNNING;
17445                final int userId = uss.mHandle.getIdentifier();
17446                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17447                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17448                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17449                broadcastIntentLocked(null, null, intent,
17450                        null, null, 0, null, null,
17451                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17452                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17453            }
17454        }
17455    }
17456
17457    void finishUserSwitch(UserStartedState uss) {
17458        synchronized (this) {
17459            finishUserBoot(uss);
17460
17461            startProfilesLocked();
17462
17463            int num = mUserLru.size();
17464            int i = 0;
17465            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17466                Integer oldUserId = mUserLru.get(i);
17467                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17468                if (oldUss == null) {
17469                    // Shouldn't happen, but be sane if it does.
17470                    mUserLru.remove(i);
17471                    num--;
17472                    continue;
17473                }
17474                if (oldUss.mState == UserStartedState.STATE_STOPPING
17475                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17476                    // This user is already stopping, doesn't count.
17477                    num--;
17478                    i++;
17479                    continue;
17480                }
17481                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17482                    // Owner and current can't be stopped, but count as running.
17483                    i++;
17484                    continue;
17485                }
17486                // This is a user to be stopped.
17487                stopUserLocked(oldUserId, null);
17488                num--;
17489                i++;
17490            }
17491        }
17492    }
17493
17494    @Override
17495    public int stopUser(final int userId, final IStopUserCallback callback) {
17496        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17497                != PackageManager.PERMISSION_GRANTED) {
17498            String msg = "Permission Denial: switchUser() from pid="
17499                    + Binder.getCallingPid()
17500                    + ", uid=" + Binder.getCallingUid()
17501                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17502            Slog.w(TAG, msg);
17503            throw new SecurityException(msg);
17504        }
17505        if (userId <= 0) {
17506            throw new IllegalArgumentException("Can't stop primary user " + userId);
17507        }
17508        synchronized (this) {
17509            return stopUserLocked(userId, callback);
17510        }
17511    }
17512
17513    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17514        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17515        if (mCurrentUserId == userId) {
17516            return ActivityManager.USER_OP_IS_CURRENT;
17517        }
17518
17519        final UserStartedState uss = mStartedUsers.get(userId);
17520        if (uss == null) {
17521            // User is not started, nothing to do...  but we do need to
17522            // callback if requested.
17523            if (callback != null) {
17524                mHandler.post(new Runnable() {
17525                    @Override
17526                    public void run() {
17527                        try {
17528                            callback.userStopped(userId);
17529                        } catch (RemoteException e) {
17530                        }
17531                    }
17532                });
17533            }
17534            return ActivityManager.USER_OP_SUCCESS;
17535        }
17536
17537        if (callback != null) {
17538            uss.mStopCallbacks.add(callback);
17539        }
17540
17541        if (uss.mState != UserStartedState.STATE_STOPPING
17542                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17543            uss.mState = UserStartedState.STATE_STOPPING;
17544            updateStartedUserArrayLocked();
17545
17546            long ident = Binder.clearCallingIdentity();
17547            try {
17548                // We are going to broadcast ACTION_USER_STOPPING and then
17549                // once that is done send a final ACTION_SHUTDOWN and then
17550                // stop the user.
17551                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17552                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17553                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17554                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17555                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17556                // This is the result receiver for the final shutdown broadcast.
17557                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17558                    @Override
17559                    public void performReceive(Intent intent, int resultCode, String data,
17560                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17561                        finishUserStop(uss);
17562                    }
17563                };
17564                // This is the result receiver for the initial stopping broadcast.
17565                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17566                    @Override
17567                    public void performReceive(Intent intent, int resultCode, String data,
17568                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17569                        // On to the next.
17570                        synchronized (ActivityManagerService.this) {
17571                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17572                                // Whoops, we are being started back up.  Abort, abort!
17573                                return;
17574                            }
17575                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17576                        }
17577                        mBatteryStatsService.noteEvent(
17578                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17579                                Integer.toString(userId), userId);
17580                        mSystemServiceManager.stopUser(userId);
17581                        broadcastIntentLocked(null, null, shutdownIntent,
17582                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17583                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17584                    }
17585                };
17586                // Kick things off.
17587                broadcastIntentLocked(null, null, stoppingIntent,
17588                        null, stoppingReceiver, 0, null, null,
17589                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17590                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17591            } finally {
17592                Binder.restoreCallingIdentity(ident);
17593            }
17594        }
17595
17596        return ActivityManager.USER_OP_SUCCESS;
17597    }
17598
17599    void finishUserStop(UserStartedState uss) {
17600        final int userId = uss.mHandle.getIdentifier();
17601        boolean stopped;
17602        ArrayList<IStopUserCallback> callbacks;
17603        synchronized (this) {
17604            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17605            if (mStartedUsers.get(userId) != uss) {
17606                stopped = false;
17607            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17608                stopped = false;
17609            } else {
17610                stopped = true;
17611                // User can no longer run.
17612                mStartedUsers.remove(userId);
17613                mUserLru.remove(Integer.valueOf(userId));
17614                updateStartedUserArrayLocked();
17615
17616                // Clean up all state and processes associated with the user.
17617                // Kill all the processes for the user.
17618                forceStopUserLocked(userId, "finish user");
17619            }
17620        }
17621
17622        for (int i=0; i<callbacks.size(); i++) {
17623            try {
17624                if (stopped) callbacks.get(i).userStopped(userId);
17625                else callbacks.get(i).userStopAborted(userId);
17626            } catch (RemoteException e) {
17627            }
17628        }
17629
17630        if (stopped) {
17631            mSystemServiceManager.cleanupUser(userId);
17632            synchronized (this) {
17633                mStackSupervisor.removeUserLocked(userId);
17634            }
17635        }
17636    }
17637
17638    @Override
17639    public UserInfo getCurrentUser() {
17640        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17641                != PackageManager.PERMISSION_GRANTED) && (
17642                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17643                != PackageManager.PERMISSION_GRANTED)) {
17644            String msg = "Permission Denial: getCurrentUser() from pid="
17645                    + Binder.getCallingPid()
17646                    + ", uid=" + Binder.getCallingUid()
17647                    + " requires " + INTERACT_ACROSS_USERS;
17648            Slog.w(TAG, msg);
17649            throw new SecurityException(msg);
17650        }
17651        synchronized (this) {
17652            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17653        }
17654    }
17655
17656    int getCurrentUserIdLocked() {
17657        return mCurrentUserId;
17658    }
17659
17660    @Override
17661    public boolean isUserRunning(int userId, boolean orStopped) {
17662        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17663                != PackageManager.PERMISSION_GRANTED) {
17664            String msg = "Permission Denial: isUserRunning() from pid="
17665                    + Binder.getCallingPid()
17666                    + ", uid=" + Binder.getCallingUid()
17667                    + " requires " + INTERACT_ACROSS_USERS;
17668            Slog.w(TAG, msg);
17669            throw new SecurityException(msg);
17670        }
17671        synchronized (this) {
17672            return isUserRunningLocked(userId, orStopped);
17673        }
17674    }
17675
17676    boolean isUserRunningLocked(int userId, boolean orStopped) {
17677        UserStartedState state = mStartedUsers.get(userId);
17678        if (state == null) {
17679            return false;
17680        }
17681        if (orStopped) {
17682            return true;
17683        }
17684        return state.mState != UserStartedState.STATE_STOPPING
17685                && state.mState != UserStartedState.STATE_SHUTDOWN;
17686    }
17687
17688    @Override
17689    public int[] getRunningUserIds() {
17690        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17691                != PackageManager.PERMISSION_GRANTED) {
17692            String msg = "Permission Denial: isUserRunning() from pid="
17693                    + Binder.getCallingPid()
17694                    + ", uid=" + Binder.getCallingUid()
17695                    + " requires " + INTERACT_ACROSS_USERS;
17696            Slog.w(TAG, msg);
17697            throw new SecurityException(msg);
17698        }
17699        synchronized (this) {
17700            return mStartedUserArray;
17701        }
17702    }
17703
17704    private void updateStartedUserArrayLocked() {
17705        int num = 0;
17706        for (int i=0; i<mStartedUsers.size();  i++) {
17707            UserStartedState uss = mStartedUsers.valueAt(i);
17708            // This list does not include stopping users.
17709            if (uss.mState != UserStartedState.STATE_STOPPING
17710                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17711                num++;
17712            }
17713        }
17714        mStartedUserArray = new int[num];
17715        num = 0;
17716        for (int i=0; i<mStartedUsers.size();  i++) {
17717            UserStartedState uss = mStartedUsers.valueAt(i);
17718            if (uss.mState != UserStartedState.STATE_STOPPING
17719                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17720                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17721                num++;
17722            }
17723        }
17724    }
17725
17726    @Override
17727    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17728        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17729                != PackageManager.PERMISSION_GRANTED) {
17730            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17731                    + Binder.getCallingPid()
17732                    + ", uid=" + Binder.getCallingUid()
17733                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17734            Slog.w(TAG, msg);
17735            throw new SecurityException(msg);
17736        }
17737
17738        mUserSwitchObservers.register(observer);
17739    }
17740
17741    @Override
17742    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17743        mUserSwitchObservers.unregister(observer);
17744    }
17745
17746    private boolean userExists(int userId) {
17747        if (userId == 0) {
17748            return true;
17749        }
17750        UserManagerService ums = getUserManagerLocked();
17751        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17752    }
17753
17754    int[] getUsersLocked() {
17755        UserManagerService ums = getUserManagerLocked();
17756        return ums != null ? ums.getUserIds() : new int[] { 0 };
17757    }
17758
17759    UserManagerService getUserManagerLocked() {
17760        if (mUserManager == null) {
17761            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17762            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17763        }
17764        return mUserManager;
17765    }
17766
17767    private int applyUserId(int uid, int userId) {
17768        return UserHandle.getUid(userId, uid);
17769    }
17770
17771    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17772        if (info == null) return null;
17773        ApplicationInfo newInfo = new ApplicationInfo(info);
17774        newInfo.uid = applyUserId(info.uid, userId);
17775        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17776                + info.packageName;
17777        return newInfo;
17778    }
17779
17780    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17781        if (aInfo == null
17782                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17783            return aInfo;
17784        }
17785
17786        ActivityInfo info = new ActivityInfo(aInfo);
17787        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17788        return info;
17789    }
17790
17791    private final class LocalService extends ActivityManagerInternal {
17792        @Override
17793        public void goingToSleep() {
17794            ActivityManagerService.this.goingToSleep();
17795        }
17796
17797        @Override
17798        public void wakingUp() {
17799            ActivityManagerService.this.wakingUp();
17800        }
17801    }
17802
17803    /**
17804     * An implementation of IAppTask, that allows an app to manage its own tasks via
17805     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17806     * only the process that calls getAppTasks() can call the AppTask methods.
17807     */
17808    class AppTaskImpl extends IAppTask.Stub {
17809        private int mTaskId;
17810        private int mCallingUid;
17811
17812        public AppTaskImpl(int taskId, int callingUid) {
17813            mTaskId = taskId;
17814            mCallingUid = callingUid;
17815        }
17816
17817        @Override
17818        public void finishAndRemoveTask() {
17819            // Ensure that we are called from the same process that created this AppTask
17820            if (mCallingUid != Binder.getCallingUid()) {
17821                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17822                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17823                return;
17824            }
17825
17826            synchronized (ActivityManagerService.this) {
17827                long origId = Binder.clearCallingIdentity();
17828                try {
17829                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17830                    if (tr != null) {
17831                        // Only kill the process if we are not a new document
17832                        int flags = tr.getBaseIntent().getFlags();
17833                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17834                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17835                        removeTaskByIdLocked(mTaskId,
17836                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17837                    }
17838                } finally {
17839                    Binder.restoreCallingIdentity(origId);
17840                }
17841            }
17842        }
17843
17844        @Override
17845        public ActivityManager.RecentTaskInfo getTaskInfo() {
17846            // Ensure that we are called from the same process that created this AppTask
17847            if (mCallingUid != Binder.getCallingUid()) {
17848                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17849                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17850                return null;
17851            }
17852
17853            synchronized (ActivityManagerService.this) {
17854                long origId = Binder.clearCallingIdentity();
17855                try {
17856                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17857                    if (tr != null) {
17858                        return createRecentTaskInfoFromTaskRecord(tr);
17859                    }
17860                } finally {
17861                    Binder.restoreCallingIdentity(origId);
17862                }
17863                return null;
17864            }
17865        }
17866    }
17867}
17868