ActivityManagerService.java revision 422570ea3fe5bf6c4dbc4d96cf47734252ffe703
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
1162    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1163    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1164    static final int FIRST_COMPAT_MODE_MSG = 300;
1165    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1166
1167    AlertDialog mUidAlert;
1168    CompatModeDialog mCompatModeDialog;
1169    long mLastMemUsageReportTime = 0;
1170
1171    private LockToAppRequestDialog mLockToAppRequest;
1172
1173    /**
1174     * Flag whether the current user is a "monkey", i.e. whether
1175     * the UI is driven by a UI automation tool.
1176     */
1177    private boolean mUserIsMonkey;
1178
1179    /** Flag whether the device has a recents UI */
1180    final boolean mHasRecents;
1181
1182    final ServiceThread mHandlerThread;
1183    final MainHandler mHandler;
1184
1185    final class MainHandler extends Handler {
1186        public MainHandler(Looper looper) {
1187            super(looper, null, true);
1188        }
1189
1190        @Override
1191        public void handleMessage(Message msg) {
1192            switch (msg.what) {
1193            case SHOW_ERROR_MSG: {
1194                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1195                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1196                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1197                synchronized (ActivityManagerService.this) {
1198                    ProcessRecord proc = (ProcessRecord)data.get("app");
1199                    AppErrorResult res = (AppErrorResult) data.get("result");
1200                    if (proc != null && proc.crashDialog != null) {
1201                        Slog.e(TAG, "App already has crash dialog: " + proc);
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                        return;
1206                    }
1207                    if (!showBackground && UserHandle.getAppId(proc.uid)
1208                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1209                            && proc.pid != MY_PID) {
1210                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1211                        if (res != null) {
1212                            res.set(0);
1213                        }
1214                        return;
1215                    }
1216                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1217                        Dialog d = new AppErrorDialog(mContext,
1218                                ActivityManagerService.this, res, proc);
1219                        d.show();
1220                        proc.crashDialog = d;
1221                    } else {
1222                        // The device is asleep, so just pretend that the user
1223                        // saw a crash dialog and hit "force quit".
1224                        if (res != null) {
1225                            res.set(0);
1226                        }
1227                    }
1228                }
1229
1230                ensureBootCompleted();
1231            } break;
1232            case SHOW_NOT_RESPONDING_MSG: {
1233                synchronized (ActivityManagerService.this) {
1234                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1235                    ProcessRecord proc = (ProcessRecord)data.get("app");
1236                    if (proc != null && proc.anrDialog != null) {
1237                        Slog.e(TAG, "App already has anr dialog: " + proc);
1238                        return;
1239                    }
1240
1241                    Intent intent = new Intent("android.intent.action.ANR");
1242                    if (!mProcessesReady) {
1243                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1244                                | Intent.FLAG_RECEIVER_FOREGROUND);
1245                    }
1246                    broadcastIntentLocked(null, null, intent,
1247                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1248                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1249
1250                    if (mShowDialogs) {
1251                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1252                                mContext, proc, (ActivityRecord)data.get("activity"),
1253                                msg.arg1 != 0);
1254                        d.show();
1255                        proc.anrDialog = d;
1256                    } else {
1257                        // Just kill the app if there is no dialog to be shown.
1258                        killAppAtUsersRequest(proc, null);
1259                    }
1260                }
1261
1262                ensureBootCompleted();
1263            } break;
1264            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1265                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1266                synchronized (ActivityManagerService.this) {
1267                    ProcessRecord proc = (ProcessRecord) data.get("app");
1268                    if (proc == null) {
1269                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1270                        break;
1271                    }
1272                    if (proc.crashDialog != null) {
1273                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1274                        return;
1275                    }
1276                    AppErrorResult res = (AppErrorResult) data.get("result");
1277                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1278                        Dialog d = new StrictModeViolationDialog(mContext,
1279                                ActivityManagerService.this, res, proc);
1280                        d.show();
1281                        proc.crashDialog = d;
1282                    } else {
1283                        // The device is asleep, so just pretend that the user
1284                        // saw a crash dialog and hit "force quit".
1285                        res.set(0);
1286                    }
1287                }
1288                ensureBootCompleted();
1289            } break;
1290            case SHOW_FACTORY_ERROR_MSG: {
1291                Dialog d = new FactoryErrorDialog(
1292                    mContext, msg.getData().getCharSequence("msg"));
1293                d.show();
1294                ensureBootCompleted();
1295            } break;
1296            case UPDATE_CONFIGURATION_MSG: {
1297                final ContentResolver resolver = mContext.getContentResolver();
1298                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1299            } break;
1300            case GC_BACKGROUND_PROCESSES_MSG: {
1301                synchronized (ActivityManagerService.this) {
1302                    performAppGcsIfAppropriateLocked();
1303                }
1304            } break;
1305            case WAIT_FOR_DEBUGGER_MSG: {
1306                synchronized (ActivityManagerService.this) {
1307                    ProcessRecord app = (ProcessRecord)msg.obj;
1308                    if (msg.arg1 != 0) {
1309                        if (!app.waitedForDebugger) {
1310                            Dialog d = new AppWaitingForDebuggerDialog(
1311                                    ActivityManagerService.this,
1312                                    mContext, app);
1313                            app.waitDialog = d;
1314                            app.waitedForDebugger = true;
1315                            d.show();
1316                        }
1317                    } else {
1318                        if (app.waitDialog != null) {
1319                            app.waitDialog.dismiss();
1320                            app.waitDialog = null;
1321                        }
1322                    }
1323                }
1324            } break;
1325            case SERVICE_TIMEOUT_MSG: {
1326                if (mDidDexOpt) {
1327                    mDidDexOpt = false;
1328                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1329                    nmsg.obj = msg.obj;
1330                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1331                    return;
1332                }
1333                mServices.serviceTimeout((ProcessRecord)msg.obj);
1334            } break;
1335            case UPDATE_TIME_ZONE: {
1336                synchronized (ActivityManagerService.this) {
1337                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1338                        ProcessRecord r = mLruProcesses.get(i);
1339                        if (r.thread != null) {
1340                            try {
1341                                r.thread.updateTimeZone();
1342                            } catch (RemoteException ex) {
1343                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1344                            }
1345                        }
1346                    }
1347                }
1348            } break;
1349            case CLEAR_DNS_CACHE_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1352                        ProcessRecord r = mLruProcesses.get(i);
1353                        if (r.thread != null) {
1354                            try {
1355                                r.thread.clearDnsCache();
1356                            } catch (RemoteException ex) {
1357                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1358                            }
1359                        }
1360                    }
1361                }
1362            } break;
1363            case UPDATE_HTTP_PROXY_MSG: {
1364                ProxyInfo proxy = (ProxyInfo)msg.obj;
1365                String host = "";
1366                String port = "";
1367                String exclList = "";
1368                Uri pacFileUrl = Uri.EMPTY;
1369                if (proxy != null) {
1370                    host = proxy.getHost();
1371                    port = Integer.toString(proxy.getPort());
1372                    exclList = proxy.getExclusionListAsString();
1373                    pacFileUrl = proxy.getPacFileUrl();
1374                }
1375                synchronized (ActivityManagerService.this) {
1376                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1377                        ProcessRecord r = mLruProcesses.get(i);
1378                        if (r.thread != null) {
1379                            try {
1380                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1381                            } catch (RemoteException ex) {
1382                                Slog.w(TAG, "Failed to update http proxy for: " +
1383                                        r.info.processName);
1384                            }
1385                        }
1386                    }
1387                }
1388            } break;
1389            case SHOW_UID_ERROR_MSG: {
1390                String title = "System UIDs Inconsistent";
1391                String text = "UIDs on the system are inconsistent, you need to wipe your"
1392                        + " data partition or your device will be unstable.";
1393                Log.e(TAG, title + ": " + text);
1394                if (mShowDialogs) {
1395                    // XXX This is a temporary dialog, no need to localize.
1396                    AlertDialog d = new BaseErrorDialog(mContext);
1397                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1398                    d.setCancelable(false);
1399                    d.setTitle(title);
1400                    d.setMessage(text);
1401                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1402                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1403                    mUidAlert = d;
1404                    d.show();
1405                }
1406            } break;
1407            case IM_FEELING_LUCKY_MSG: {
1408                if (mUidAlert != null) {
1409                    mUidAlert.dismiss();
1410                    mUidAlert = null;
1411                }
1412            } break;
1413            case PROC_START_TIMEOUT_MSG: {
1414                if (mDidDexOpt) {
1415                    mDidDexOpt = false;
1416                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1417                    nmsg.obj = msg.obj;
1418                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1419                    return;
1420                }
1421                ProcessRecord app = (ProcessRecord)msg.obj;
1422                synchronized (ActivityManagerService.this) {
1423                    processStartTimedOutLocked(app);
1424                }
1425            } break;
1426            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1427                synchronized (ActivityManagerService.this) {
1428                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1429                }
1430            } break;
1431            case KILL_APPLICATION_MSG: {
1432                synchronized (ActivityManagerService.this) {
1433                    int appid = msg.arg1;
1434                    boolean restart = (msg.arg2 == 1);
1435                    Bundle bundle = (Bundle)msg.obj;
1436                    String pkg = bundle.getString("pkg");
1437                    String reason = bundle.getString("reason");
1438                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1439                            false, UserHandle.USER_ALL, reason);
1440                }
1441            } break;
1442            case FINALIZE_PENDING_INTENT_MSG: {
1443                ((PendingIntentRecord)msg.obj).completeFinalize();
1444            } break;
1445            case POST_HEAVY_NOTIFICATION_MSG: {
1446                INotificationManager inm = NotificationManager.getService();
1447                if (inm == null) {
1448                    return;
1449                }
1450
1451                ActivityRecord root = (ActivityRecord)msg.obj;
1452                ProcessRecord process = root.app;
1453                if (process == null) {
1454                    return;
1455                }
1456
1457                try {
1458                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1459                    String text = mContext.getString(R.string.heavy_weight_notification,
1460                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1461                    Notification notification = new Notification();
1462                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1463                    notification.when = 0;
1464                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1465                    notification.tickerText = text;
1466                    notification.defaults = 0; // please be quiet
1467                    notification.sound = null;
1468                    notification.vibrate = null;
1469                    notification.setLatestEventInfo(context, text,
1470                            mContext.getText(R.string.heavy_weight_notification_detail),
1471                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1472                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1473                                    new UserHandle(root.userId)));
1474
1475                    try {
1476                        int[] outId = new int[1];
1477                        inm.enqueueNotificationWithTag("android", "android", null,
1478                                R.string.heavy_weight_notification,
1479                                notification, outId, root.userId);
1480                    } catch (RuntimeException e) {
1481                        Slog.w(ActivityManagerService.TAG,
1482                                "Error showing notification for heavy-weight app", e);
1483                    } catch (RemoteException e) {
1484                    }
1485                } catch (NameNotFoundException e) {
1486                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1487                }
1488            } break;
1489            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1490                INotificationManager inm = NotificationManager.getService();
1491                if (inm == null) {
1492                    return;
1493                }
1494                try {
1495                    inm.cancelNotificationWithTag("android", null,
1496                            R.string.heavy_weight_notification,  msg.arg1);
1497                } catch (RuntimeException e) {
1498                    Slog.w(ActivityManagerService.TAG,
1499                            "Error canceling notification for service", e);
1500                } catch (RemoteException e) {
1501                }
1502            } break;
1503            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1504                synchronized (ActivityManagerService.this) {
1505                    checkExcessivePowerUsageLocked(true);
1506                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1507                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1509                }
1510            } break;
1511            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    ActivityRecord ar = (ActivityRecord)msg.obj;
1514                    if (mCompatModeDialog != null) {
1515                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1516                                ar.info.applicationInfo.packageName)) {
1517                            return;
1518                        }
1519                        mCompatModeDialog.dismiss();
1520                        mCompatModeDialog = null;
1521                    }
1522                    if (ar != null && false) {
1523                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1524                                ar.packageName)) {
1525                            int mode = mCompatModePackages.computeCompatModeLocked(
1526                                    ar.info.applicationInfo);
1527                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1528                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1529                                mCompatModeDialog = new CompatModeDialog(
1530                                        ActivityManagerService.this, mContext,
1531                                        ar.info.applicationInfo);
1532                                mCompatModeDialog.show();
1533                            }
1534                        }
1535                    }
1536                }
1537                break;
1538            }
1539            case DISPATCH_PROCESSES_CHANGED: {
1540                dispatchProcessesChanged();
1541                break;
1542            }
1543            case DISPATCH_PROCESS_DIED: {
1544                final int pid = msg.arg1;
1545                final int uid = msg.arg2;
1546                dispatchProcessDied(pid, uid);
1547                break;
1548            }
1549            case REPORT_MEM_USAGE_MSG: {
1550                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1551                Thread thread = new Thread() {
1552                    @Override public void run() {
1553                        final SparseArray<ProcessMemInfo> infoMap
1554                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1555                        for (int i=0, N=memInfos.size(); i<N; i++) {
1556                            ProcessMemInfo mi = memInfos.get(i);
1557                            infoMap.put(mi.pid, mi);
1558                        }
1559                        updateCpuStatsNow();
1560                        synchronized (mProcessCpuThread) {
1561                            final int N = mProcessCpuTracker.countStats();
1562                            for (int i=0; i<N; i++) {
1563                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1564                                if (st.vsize > 0) {
1565                                    long pss = Debug.getPss(st.pid, null);
1566                                    if (pss > 0) {
1567                                        if (infoMap.indexOfKey(st.pid) < 0) {
1568                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1569                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1570                                            mi.pss = pss;
1571                                            memInfos.add(mi);
1572                                        }
1573                                    }
1574                                }
1575                            }
1576                        }
1577
1578                        long totalPss = 0;
1579                        for (int i=0, N=memInfos.size(); i<N; i++) {
1580                            ProcessMemInfo mi = memInfos.get(i);
1581                            if (mi.pss == 0) {
1582                                mi.pss = Debug.getPss(mi.pid, null);
1583                            }
1584                            totalPss += mi.pss;
1585                        }
1586                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1587                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1588                                if (lhs.oomAdj != rhs.oomAdj) {
1589                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1590                                }
1591                                if (lhs.pss != rhs.pss) {
1592                                    return lhs.pss < rhs.pss ? 1 : -1;
1593                                }
1594                                return 0;
1595                            }
1596                        });
1597
1598                        StringBuilder tag = new StringBuilder(128);
1599                        StringBuilder stack = new StringBuilder(128);
1600                        tag.append("Low on memory -- ");
1601                        appendMemBucket(tag, totalPss, "total", false);
1602                        appendMemBucket(stack, totalPss, "total", true);
1603
1604                        StringBuilder logBuilder = new StringBuilder(1024);
1605                        logBuilder.append("Low on memory:\n");
1606
1607                        boolean firstLine = true;
1608                        int lastOomAdj = Integer.MIN_VALUE;
1609                        for (int i=0, N=memInfos.size(); i<N; i++) {
1610                            ProcessMemInfo mi = memInfos.get(i);
1611
1612                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1613                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1614                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1615                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1616                                if (lastOomAdj != mi.oomAdj) {
1617                                    lastOomAdj = mi.oomAdj;
1618                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1619                                        tag.append(" / ");
1620                                    }
1621                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1622                                        if (firstLine) {
1623                                            stack.append(":");
1624                                            firstLine = false;
1625                                        }
1626                                        stack.append("\n\t at ");
1627                                    } else {
1628                                        stack.append("$");
1629                                    }
1630                                } else {
1631                                    tag.append(" ");
1632                                    stack.append("$");
1633                                }
1634                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1635                                    appendMemBucket(tag, mi.pss, mi.name, false);
1636                                }
1637                                appendMemBucket(stack, mi.pss, mi.name, true);
1638                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1639                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1640                                    stack.append("(");
1641                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1642                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1643                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1644                                            stack.append(":");
1645                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1646                                        }
1647                                    }
1648                                    stack.append(")");
1649                                }
1650                            }
1651
1652                            logBuilder.append("  ");
1653                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1654                            logBuilder.append(' ');
1655                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1656                            logBuilder.append(' ');
1657                            ProcessList.appendRamKb(logBuilder, mi.pss);
1658                            logBuilder.append(" kB: ");
1659                            logBuilder.append(mi.name);
1660                            logBuilder.append(" (");
1661                            logBuilder.append(mi.pid);
1662                            logBuilder.append(") ");
1663                            logBuilder.append(mi.adjType);
1664                            logBuilder.append('\n');
1665                            if (mi.adjReason != null) {
1666                                logBuilder.append("                      ");
1667                                logBuilder.append(mi.adjReason);
1668                                logBuilder.append('\n');
1669                            }
1670                        }
1671
1672                        logBuilder.append("           ");
1673                        ProcessList.appendRamKb(logBuilder, totalPss);
1674                        logBuilder.append(" kB: TOTAL\n");
1675
1676                        long[] infos = new long[Debug.MEMINFO_COUNT];
1677                        Debug.getMemInfo(infos);
1678                        logBuilder.append("  MemInfo: ");
1679                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1684                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1685                            logBuilder.append("  ZRAM: ");
1686                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1687                            logBuilder.append(" kB RAM, ");
1688                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1689                            logBuilder.append(" kB swap total, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1691                            logBuilder.append(" kB swap free\n");
1692                        }
1693                        Slog.i(TAG, logBuilder.toString());
1694
1695                        StringBuilder dropBuilder = new StringBuilder(1024);
1696                        /*
1697                        StringWriter oomSw = new StringWriter();
1698                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1699                        StringWriter catSw = new StringWriter();
1700                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1701                        String[] emptyArgs = new String[] { };
1702                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1703                        oomPw.flush();
1704                        String oomString = oomSw.toString();
1705                        */
1706                        dropBuilder.append(stack);
1707                        dropBuilder.append('\n');
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append(logBuilder);
1710                        dropBuilder.append('\n');
1711                        /*
1712                        dropBuilder.append(oomString);
1713                        dropBuilder.append('\n');
1714                        */
1715                        StringWriter catSw = new StringWriter();
1716                        synchronized (ActivityManagerService.this) {
1717                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1718                            String[] emptyArgs = new String[] { };
1719                            catPw.println();
1720                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1721                            catPw.println();
1722                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1723                                    false, false, null);
1724                            catPw.println();
1725                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1726                            catPw.flush();
1727                        }
1728                        dropBuilder.append(catSw.toString());
1729                        addErrorToDropBox("lowmem", null, "system_server", null,
1730                                null, tag.toString(), dropBuilder.toString(), null, null);
1731                        //Slog.i(TAG, "Sent to dropbox:");
1732                        //Slog.i(TAG, dropBuilder.toString());
1733                        synchronized (ActivityManagerService.this) {
1734                            long now = SystemClock.uptimeMillis();
1735                            if (mLastMemUsageReportTime < now) {
1736                                mLastMemUsageReportTime = now;
1737                            }
1738                        }
1739                    }
1740                };
1741                thread.start();
1742                break;
1743            }
1744            case REPORT_USER_SWITCH_MSG: {
1745                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1746                break;
1747            }
1748            case CONTINUE_USER_SWITCH_MSG: {
1749                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1750                break;
1751            }
1752            case USER_SWITCH_TIMEOUT_MSG: {
1753                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1754                break;
1755            }
1756            case IMMERSIVE_MODE_LOCK_MSG: {
1757                final boolean nextState = (msg.arg1 != 0);
1758                if (mUpdateLock.isHeld() != nextState) {
1759                    if (DEBUG_IMMERSIVE) {
1760                        final ActivityRecord r = (ActivityRecord) msg.obj;
1761                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1762                    }
1763                    if (nextState) {
1764                        mUpdateLock.acquire();
1765                    } else {
1766                        mUpdateLock.release();
1767                    }
1768                }
1769                break;
1770            }
1771            case PERSIST_URI_GRANTS_MSG: {
1772                writeGrantedUriPermissions();
1773                break;
1774            }
1775            case REQUEST_ALL_PSS_MSG: {
1776                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1777                break;
1778            }
1779            case START_PROFILES_MSG: {
1780                synchronized (ActivityManagerService.this) {
1781                    startProfilesLocked();
1782                }
1783                break;
1784            }
1785            case UPDATE_TIME: {
1786                synchronized (ActivityManagerService.this) {
1787                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1788                        ProcessRecord r = mLruProcesses.get(i);
1789                        if (r.thread != null) {
1790                            try {
1791                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1792                            } catch (RemoteException ex) {
1793                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1794                            }
1795                        }
1796                    }
1797                }
1798                break;
1799            }
1800            case SYSTEM_USER_START_MSG: {
1801                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1802                        Integer.toString(msg.arg1), msg.arg1);
1803                mSystemServiceManager.startUser(msg.arg1);
1804                break;
1805            }
1806            case SYSTEM_USER_CURRENT_MSG: {
1807                mBatteryStatsService.noteEvent(
1808                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1809                        Integer.toString(msg.arg2), msg.arg2);
1810                mBatteryStatsService.noteEvent(
1811                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1812                        Integer.toString(msg.arg1), msg.arg1);
1813                mSystemServiceManager.switchUser(msg.arg1);
1814                break;
1815            }
1816            }
1817        }
1818    };
1819
1820    static final int COLLECT_PSS_BG_MSG = 1;
1821
1822    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1823        @Override
1824        public void handleMessage(Message msg) {
1825            switch (msg.what) {
1826            case COLLECT_PSS_BG_MSG: {
1827                long start = SystemClock.uptimeMillis();
1828                MemInfoReader memInfo = null;
1829                synchronized (ActivityManagerService.this) {
1830                    if (mFullPssPending) {
1831                        mFullPssPending = false;
1832                        memInfo = new MemInfoReader();
1833                    }
1834                }
1835                if (memInfo != null) {
1836                    updateCpuStatsNow();
1837                    long nativeTotalPss = 0;
1838                    synchronized (mProcessCpuThread) {
1839                        final int N = mProcessCpuTracker.countStats();
1840                        for (int j=0; j<N; j++) {
1841                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1842                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1843                                // This is definitely an application process; skip it.
1844                                continue;
1845                            }
1846                            synchronized (mPidsSelfLocked) {
1847                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1848                                    // This is one of our own processes; skip it.
1849                                    continue;
1850                                }
1851                            }
1852                            nativeTotalPss += Debug.getPss(st.pid, null);
1853                        }
1854                    }
1855                    memInfo.readMemInfo();
1856                    synchronized (this) {
1857                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1858                                + (SystemClock.uptimeMillis()-start) + "ms");
1859                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1860                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1861                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1862                                        +memInfo.getSlabSizeKb(),
1863                                nativeTotalPss);
1864                    }
1865                }
1866
1867                int i=0, num=0;
1868                long[] tmp = new long[1];
1869                do {
1870                    ProcessRecord proc;
1871                    int procState;
1872                    int pid;
1873                    synchronized (ActivityManagerService.this) {
1874                        if (i >= mPendingPssProcesses.size()) {
1875                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1876                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1877                            mPendingPssProcesses.clear();
1878                            return;
1879                        }
1880                        proc = mPendingPssProcesses.get(i);
1881                        procState = proc.pssProcState;
1882                        if (proc.thread != null && procState == proc.setProcState) {
1883                            pid = proc.pid;
1884                        } else {
1885                            proc = null;
1886                            pid = 0;
1887                        }
1888                        i++;
1889                    }
1890                    if (proc != null) {
1891                        long pss = Debug.getPss(pid, tmp);
1892                        synchronized (ActivityManagerService.this) {
1893                            if (proc.thread != null && proc.setProcState == procState
1894                                    && proc.pid == pid) {
1895                                num++;
1896                                proc.lastPssTime = SystemClock.uptimeMillis();
1897                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1898                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1899                                        + ": " + pss + " lastPss=" + proc.lastPss
1900                                        + " state=" + ProcessList.makeProcStateString(procState));
1901                                if (proc.initialIdlePss == 0) {
1902                                    proc.initialIdlePss = pss;
1903                                }
1904                                proc.lastPss = pss;
1905                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1906                                    proc.lastCachedPss = pss;
1907                                }
1908                            }
1909                        }
1910                    }
1911                } while (true);
1912            }
1913            }
1914        }
1915    };
1916
1917    /**
1918     * Monitor for package changes and update our internal state.
1919     */
1920    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1921        @Override
1922        public void onPackageRemoved(String packageName, int uid) {
1923            // Remove all tasks with activities in the specified package from the list of recent tasks
1924            synchronized (ActivityManagerService.this) {
1925                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1926                    TaskRecord tr = mRecentTasks.get(i);
1927                    ComponentName cn = tr.intent.getComponent();
1928                    if (cn != null && cn.getPackageName().equals(packageName)) {
1929                        // If the package name matches, remove the task and kill the process
1930                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1931                    }
1932                }
1933            }
1934        }
1935
1936        @Override
1937        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1938            onPackageModified(packageName);
1939            return true;
1940        }
1941
1942        @Override
1943        public void onPackageModified(String packageName) {
1944            final PackageManager pm = mContext.getPackageManager();
1945            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1946                    new ArrayList<Pair<Intent, Integer>>();
1947            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1948            // Copy the list of recent tasks so that we don't hold onto the lock on
1949            // ActivityManagerService for long periods while checking if components exist.
1950            synchronized (ActivityManagerService.this) {
1951                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1952                    TaskRecord tr = mRecentTasks.get(i);
1953                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1954                }
1955            }
1956            // Check the recent tasks and filter out all tasks with components that no longer exist.
1957            Intent tmpI = new Intent();
1958            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1959                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1960                ComponentName cn = p.first.getComponent();
1961                if (cn != null && cn.getPackageName().equals(packageName)) {
1962                    try {
1963                        // Add the task to the list to remove if the component no longer exists
1964                        tmpI.setComponent(cn);
1965                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1966                            tasksToRemove.add(p.second);
1967                        }
1968                    } catch (Exception e) {}
1969                }
1970            }
1971            // Prune all the tasks with removed components from the list of recent tasks
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1974                    // Remove the task but don't kill the process (since other components in that
1975                    // package may still be running and in the background)
1976                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1977                }
1978            }
1979        }
1980
1981        @Override
1982        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1983            // Force stop the specified packages
1984            if (packages != null) {
1985                for (String pkg : packages) {
1986                    synchronized (ActivityManagerService.this) {
1987                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1988                                "finished booting")) {
1989                            return true;
1990                        }
1991                    }
1992                }
1993            }
1994            return false;
1995        }
1996    };
1997
1998    public void setSystemProcess() {
1999        try {
2000            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2001            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2002            ServiceManager.addService("meminfo", new MemBinder(this));
2003            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2004            ServiceManager.addService("dbinfo", new DbBinder(this));
2005            if (MONITOR_CPU_USAGE) {
2006                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2007            }
2008            ServiceManager.addService("permission", new PermissionController(this));
2009
2010            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2011                    "android", STOCK_PM_FLAGS);
2012            mSystemThread.installSystemApplicationInfo(info);
2013
2014            synchronized (this) {
2015                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2016                app.persistent = true;
2017                app.pid = MY_PID;
2018                app.maxAdj = ProcessList.SYSTEM_ADJ;
2019                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2020                mProcessNames.put(app.processName, app.uid, app);
2021                synchronized (mPidsSelfLocked) {
2022                    mPidsSelfLocked.put(app.pid, app);
2023                }
2024                updateLruProcessLocked(app, false, null);
2025                updateOomAdjLocked();
2026            }
2027        } catch (PackageManager.NameNotFoundException e) {
2028            throw new RuntimeException(
2029                    "Unable to find android system package", e);
2030        }
2031    }
2032
2033    public void setWindowManager(WindowManagerService wm) {
2034        mWindowManager = wm;
2035        mStackSupervisor.setWindowManager(wm);
2036    }
2037
2038    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2039        mUsageStatsService = usageStatsManager;
2040    }
2041
2042    public void startObservingNativeCrashes() {
2043        final NativeCrashListener ncl = new NativeCrashListener(this);
2044        ncl.start();
2045    }
2046
2047    public IAppOpsService getAppOpsService() {
2048        return mAppOpsService;
2049    }
2050
2051    static class MemBinder extends Binder {
2052        ActivityManagerService mActivityManagerService;
2053        MemBinder(ActivityManagerService activityManagerService) {
2054            mActivityManagerService = activityManagerService;
2055        }
2056
2057        @Override
2058        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2059            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2060                    != PackageManager.PERMISSION_GRANTED) {
2061                pw.println("Permission Denial: can't dump meminfo from from pid="
2062                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2063                        + " without permission " + android.Manifest.permission.DUMP);
2064                return;
2065            }
2066
2067            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2068        }
2069    }
2070
2071    static class GraphicsBinder extends Binder {
2072        ActivityManagerService mActivityManagerService;
2073        GraphicsBinder(ActivityManagerService activityManagerService) {
2074            mActivityManagerService = activityManagerService;
2075        }
2076
2077        @Override
2078        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2079            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2080                    != PackageManager.PERMISSION_GRANTED) {
2081                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2082                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2083                        + " without permission " + android.Manifest.permission.DUMP);
2084                return;
2085            }
2086
2087            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2088        }
2089    }
2090
2091    static class DbBinder extends Binder {
2092        ActivityManagerService mActivityManagerService;
2093        DbBinder(ActivityManagerService activityManagerService) {
2094            mActivityManagerService = activityManagerService;
2095        }
2096
2097        @Override
2098        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2099            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2100                    != PackageManager.PERMISSION_GRANTED) {
2101                pw.println("Permission Denial: can't dump dbinfo from from pid="
2102                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2103                        + " without permission " + android.Manifest.permission.DUMP);
2104                return;
2105            }
2106
2107            mActivityManagerService.dumpDbInfo(fd, pw, args);
2108        }
2109    }
2110
2111    static class CpuBinder extends Binder {
2112        ActivityManagerService mActivityManagerService;
2113        CpuBinder(ActivityManagerService activityManagerService) {
2114            mActivityManagerService = activityManagerService;
2115        }
2116
2117        @Override
2118        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2119            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2120                    != PackageManager.PERMISSION_GRANTED) {
2121                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2122                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2123                        + " without permission " + android.Manifest.permission.DUMP);
2124                return;
2125            }
2126
2127            synchronized (mActivityManagerService.mProcessCpuThread) {
2128                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2129                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2130                        SystemClock.uptimeMillis()));
2131            }
2132        }
2133    }
2134
2135    public static final class Lifecycle extends SystemService {
2136        private final ActivityManagerService mService;
2137
2138        public Lifecycle(Context context) {
2139            super(context);
2140            mService = new ActivityManagerService(context);
2141        }
2142
2143        @Override
2144        public void onStart() {
2145            mService.start();
2146        }
2147
2148        public ActivityManagerService getService() {
2149            return mService;
2150        }
2151    }
2152
2153    // Note: This method is invoked on the main thread but may need to attach various
2154    // handlers to other threads.  So take care to be explicit about the looper.
2155    public ActivityManagerService(Context systemContext) {
2156        mContext = systemContext;
2157        mFactoryTest = FactoryTest.getMode();
2158        mSystemThread = ActivityThread.currentActivityThread();
2159
2160        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2161
2162        mHandlerThread = new ServiceThread(TAG,
2163                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2164        mHandlerThread.start();
2165        mHandler = new MainHandler(mHandlerThread.getLooper());
2166
2167        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2168                "foreground", BROADCAST_FG_TIMEOUT, false);
2169        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2170                "background", BROADCAST_BG_TIMEOUT, true);
2171        mBroadcastQueues[0] = mFgBroadcastQueue;
2172        mBroadcastQueues[1] = mBgBroadcastQueue;
2173
2174        mServices = new ActiveServices(this);
2175        mProviderMap = new ProviderMap(this);
2176
2177        // TODO: Move creation of battery stats service outside of activity manager service.
2178        File dataDir = Environment.getDataDirectory();
2179        File systemDir = new File(dataDir, "system");
2180        systemDir.mkdirs();
2181        mBatteryStatsService = new BatteryStatsService(new File(
2182                systemDir, "batterystats.bin").toString(), mHandler);
2183        mBatteryStatsService.getActiveStatistics().readLocked();
2184        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2185        mOnBattery = DEBUG_POWER ? true
2186                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2187        mBatteryStatsService.getActiveStatistics().setCallback(this);
2188
2189        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2190
2191        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2192
2193        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2194
2195        // User 0 is the first and only user that runs at boot.
2196        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2197        mUserLru.add(Integer.valueOf(0));
2198        updateStartedUserArrayLocked();
2199
2200        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2201            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2202
2203        mConfiguration.setToDefaults();
2204        mConfiguration.setLocale(Locale.getDefault());
2205
2206        mConfigurationSeq = mConfiguration.seq = 1;
2207        mProcessCpuTracker.init();
2208
2209        mHasRecents = mContext.getResources().getBoolean(
2210                com.android.internal.R.bool.config_hasRecents);
2211
2212        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2213        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2214        mStackSupervisor = new ActivityStackSupervisor(this);
2215        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2216
2217        mProcessCpuThread = new Thread("CpuTracker") {
2218            @Override
2219            public void run() {
2220                while (true) {
2221                    try {
2222                        try {
2223                            synchronized(this) {
2224                                final long now = SystemClock.uptimeMillis();
2225                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2226                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2227                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2228                                //        + ", write delay=" + nextWriteDelay);
2229                                if (nextWriteDelay < nextCpuDelay) {
2230                                    nextCpuDelay = nextWriteDelay;
2231                                }
2232                                if (nextCpuDelay > 0) {
2233                                    mProcessCpuMutexFree.set(true);
2234                                    this.wait(nextCpuDelay);
2235                                }
2236                            }
2237                        } catch (InterruptedException e) {
2238                        }
2239                        updateCpuStatsNow();
2240                    } catch (Exception e) {
2241                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2242                    }
2243                }
2244            }
2245        };
2246
2247        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2248
2249        Watchdog.getInstance().addMonitor(this);
2250        Watchdog.getInstance().addThread(mHandler);
2251    }
2252
2253    public void setSystemServiceManager(SystemServiceManager mgr) {
2254        mSystemServiceManager = mgr;
2255    }
2256
2257    private void start() {
2258        Process.removeAllProcessGroups();
2259        mProcessCpuThread.start();
2260
2261        mBatteryStatsService.publish(mContext);
2262        mAppOpsService.publish(mContext);
2263        Slog.d("AppOps", "AppOpsService published");
2264        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2265    }
2266
2267    public void initPowerManagement() {
2268        mStackSupervisor.initPowerManagement();
2269        mBatteryStatsService.initPowerManagement();
2270    }
2271
2272    @Override
2273    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2274            throws RemoteException {
2275        if (code == SYSPROPS_TRANSACTION) {
2276            // We need to tell all apps about the system property change.
2277            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2278            synchronized(this) {
2279                final int NP = mProcessNames.getMap().size();
2280                for (int ip=0; ip<NP; ip++) {
2281                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2282                    final int NA = apps.size();
2283                    for (int ia=0; ia<NA; ia++) {
2284                        ProcessRecord app = apps.valueAt(ia);
2285                        if (app.thread != null) {
2286                            procs.add(app.thread.asBinder());
2287                        }
2288                    }
2289                }
2290            }
2291
2292            int N = procs.size();
2293            for (int i=0; i<N; i++) {
2294                Parcel data2 = Parcel.obtain();
2295                try {
2296                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2297                } catch (RemoteException e) {
2298                }
2299                data2.recycle();
2300            }
2301        }
2302        try {
2303            return super.onTransact(code, data, reply, flags);
2304        } catch (RuntimeException e) {
2305            // The activity manager only throws security exceptions, so let's
2306            // log all others.
2307            if (!(e instanceof SecurityException)) {
2308                Slog.wtf(TAG, "Activity Manager Crash", e);
2309            }
2310            throw e;
2311        }
2312    }
2313
2314    void updateCpuStats() {
2315        final long now = SystemClock.uptimeMillis();
2316        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2317            return;
2318        }
2319        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2320            synchronized (mProcessCpuThread) {
2321                mProcessCpuThread.notify();
2322            }
2323        }
2324    }
2325
2326    void updateCpuStatsNow() {
2327        synchronized (mProcessCpuThread) {
2328            mProcessCpuMutexFree.set(false);
2329            final long now = SystemClock.uptimeMillis();
2330            boolean haveNewCpuStats = false;
2331
2332            if (MONITOR_CPU_USAGE &&
2333                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2334                mLastCpuTime.set(now);
2335                haveNewCpuStats = true;
2336                mProcessCpuTracker.update();
2337                //Slog.i(TAG, mProcessCpu.printCurrentState());
2338                //Slog.i(TAG, "Total CPU usage: "
2339                //        + mProcessCpu.getTotalCpuPercent() + "%");
2340
2341                // Slog the cpu usage if the property is set.
2342                if ("true".equals(SystemProperties.get("events.cpu"))) {
2343                    int user = mProcessCpuTracker.getLastUserTime();
2344                    int system = mProcessCpuTracker.getLastSystemTime();
2345                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2346                    int irq = mProcessCpuTracker.getLastIrqTime();
2347                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2348                    int idle = mProcessCpuTracker.getLastIdleTime();
2349
2350                    int total = user + system + iowait + irq + softIrq + idle;
2351                    if (total == 0) total = 1;
2352
2353                    EventLog.writeEvent(EventLogTags.CPU,
2354                            ((user+system+iowait+irq+softIrq) * 100) / total,
2355                            (user * 100) / total,
2356                            (system * 100) / total,
2357                            (iowait * 100) / total,
2358                            (irq * 100) / total,
2359                            (softIrq * 100) / total);
2360                }
2361            }
2362
2363            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2364            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2365            synchronized(bstats) {
2366                synchronized(mPidsSelfLocked) {
2367                    if (haveNewCpuStats) {
2368                        if (mOnBattery) {
2369                            int perc = bstats.startAddingCpuLocked();
2370                            int totalUTime = 0;
2371                            int totalSTime = 0;
2372                            final int N = mProcessCpuTracker.countStats();
2373                            for (int i=0; i<N; i++) {
2374                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2375                                if (!st.working) {
2376                                    continue;
2377                                }
2378                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2379                                int otherUTime = (st.rel_utime*perc)/100;
2380                                int otherSTime = (st.rel_stime*perc)/100;
2381                                totalUTime += otherUTime;
2382                                totalSTime += otherSTime;
2383                                if (pr != null) {
2384                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2385                                    if (ps == null || !ps.isActive()) {
2386                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2387                                                pr.info.uid, pr.processName);
2388                                    }
2389                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2390                                            st.rel_stime-otherSTime);
2391                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2392                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2393                                } else {
2394                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2395                                    if (ps == null || !ps.isActive()) {
2396                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2397                                                bstats.mapUid(st.uid), st.name);
2398                                    }
2399                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2400                                            st.rel_stime-otherSTime);
2401                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2402                                }
2403                            }
2404                            bstats.finishAddingCpuLocked(perc, totalUTime,
2405                                    totalSTime, cpuSpeedTimes);
2406                        }
2407                    }
2408                }
2409
2410                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2411                    mLastWriteTime = now;
2412                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2413                }
2414            }
2415        }
2416    }
2417
2418    @Override
2419    public void batteryNeedsCpuUpdate() {
2420        updateCpuStatsNow();
2421    }
2422
2423    @Override
2424    public void batteryPowerChanged(boolean onBattery) {
2425        // When plugging in, update the CPU stats first before changing
2426        // the plug state.
2427        updateCpuStatsNow();
2428        synchronized (this) {
2429            synchronized(mPidsSelfLocked) {
2430                mOnBattery = DEBUG_POWER ? true : onBattery;
2431            }
2432        }
2433    }
2434
2435    /**
2436     * Initialize the application bind args. These are passed to each
2437     * process when the bindApplication() IPC is sent to the process. They're
2438     * lazily setup to make sure the services are running when they're asked for.
2439     */
2440    private HashMap<String, IBinder> getCommonServicesLocked() {
2441        if (mAppBindArgs == null) {
2442            mAppBindArgs = new HashMap<String, IBinder>();
2443
2444            // Setup the application init args
2445            mAppBindArgs.put("package", ServiceManager.getService("package"));
2446            mAppBindArgs.put("window", ServiceManager.getService("window"));
2447            mAppBindArgs.put(Context.ALARM_SERVICE,
2448                    ServiceManager.getService(Context.ALARM_SERVICE));
2449        }
2450        return mAppBindArgs;
2451    }
2452
2453    final void setFocusedActivityLocked(ActivityRecord r) {
2454        if (mFocusedActivity != r) {
2455            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2456            mFocusedActivity = r;
2457            if (r.task != null && r.task.voiceInteractor != null) {
2458                startRunningVoiceLocked();
2459            } else {
2460                finishRunningVoiceLocked();
2461            }
2462            mStackSupervisor.setFocusedStack(r);
2463            if (r != null) {
2464                mWindowManager.setFocusedApp(r.appToken, true);
2465            }
2466            applyUpdateLockStateLocked(r);
2467        }
2468    }
2469
2470    final void clearFocusedActivity(ActivityRecord r) {
2471        if (mFocusedActivity == r) {
2472            mFocusedActivity = null;
2473        }
2474    }
2475
2476    @Override
2477    public void setFocusedStack(int stackId) {
2478        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2479        synchronized (ActivityManagerService.this) {
2480            ActivityStack stack = mStackSupervisor.getStack(stackId);
2481            if (stack != null) {
2482                ActivityRecord r = stack.topRunningActivityLocked(null);
2483                if (r != null) {
2484                    setFocusedActivityLocked(r);
2485                }
2486            }
2487        }
2488    }
2489
2490    @Override
2491    public void notifyActivityDrawn(IBinder token) {
2492        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2493        synchronized (this) {
2494            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2495            if (r != null) {
2496                r.task.stack.notifyActivityDrawnLocked(r);
2497            }
2498        }
2499    }
2500
2501    final void applyUpdateLockStateLocked(ActivityRecord r) {
2502        // Modifications to the UpdateLock state are done on our handler, outside
2503        // the activity manager's locks.  The new state is determined based on the
2504        // state *now* of the relevant activity record.  The object is passed to
2505        // the handler solely for logging detail, not to be consulted/modified.
2506        final boolean nextState = r != null && r.immersive;
2507        mHandler.sendMessage(
2508                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2509    }
2510
2511    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2512        Message msg = Message.obtain();
2513        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2514        msg.obj = r.task.askedCompatMode ? null : r;
2515        mHandler.sendMessage(msg);
2516    }
2517
2518    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2519            String what, Object obj, ProcessRecord srcApp) {
2520        app.lastActivityTime = now;
2521
2522        if (app.activities.size() > 0) {
2523            // Don't want to touch dependent processes that are hosting activities.
2524            return index;
2525        }
2526
2527        int lrui = mLruProcesses.lastIndexOf(app);
2528        if (lrui < 0) {
2529            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2530                    + what + " " + obj + " from " + srcApp);
2531            return index;
2532        }
2533
2534        if (lrui >= index) {
2535            // Don't want to cause this to move dependent processes *back* in the
2536            // list as if they were less frequently used.
2537            return index;
2538        }
2539
2540        if (lrui >= mLruProcessActivityStart) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        mLruProcesses.remove(lrui);
2546        if (index > 0) {
2547            index--;
2548        }
2549        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2550                + " in LRU list: " + app);
2551        mLruProcesses.add(index, app);
2552        return index;
2553    }
2554
2555    final void removeLruProcessLocked(ProcessRecord app) {
2556        int lrui = mLruProcesses.lastIndexOf(app);
2557        if (lrui >= 0) {
2558            if (lrui <= mLruProcessActivityStart) {
2559                mLruProcessActivityStart--;
2560            }
2561            if (lrui <= mLruProcessServiceStart) {
2562                mLruProcessServiceStart--;
2563            }
2564            mLruProcesses.remove(lrui);
2565        }
2566    }
2567
2568    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2569            ProcessRecord client) {
2570        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2571                || app.treatLikeActivity;
2572        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2573        if (!activityChange && hasActivity) {
2574            // The process has activities, so we are only allowing activity-based adjustments
2575            // to move it.  It should be kept in the front of the list with other
2576            // processes that have activities, and we don't want those to change their
2577            // order except due to activity operations.
2578            return;
2579        }
2580
2581        mLruSeq++;
2582        final long now = SystemClock.uptimeMillis();
2583        app.lastActivityTime = now;
2584
2585        // First a quick reject: if the app is already at the position we will
2586        // put it, then there is nothing to do.
2587        if (hasActivity) {
2588            final int N = mLruProcesses.size();
2589            if (N > 0 && mLruProcesses.get(N-1) == app) {
2590                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2591                return;
2592            }
2593        } else {
2594            if (mLruProcessServiceStart > 0
2595                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2596                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2597                return;
2598            }
2599        }
2600
2601        int lrui = mLruProcesses.lastIndexOf(app);
2602
2603        if (app.persistent && lrui >= 0) {
2604            // We don't care about the position of persistent processes, as long as
2605            // they are in the list.
2606            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2607            return;
2608        }
2609
2610        /* In progress: compute new position first, so we can avoid doing work
2611           if the process is not actually going to move.  Not yet working.
2612        int addIndex;
2613        int nextIndex;
2614        boolean inActivity = false, inService = false;
2615        if (hasActivity) {
2616            // Process has activities, put it at the very tipsy-top.
2617            addIndex = mLruProcesses.size();
2618            nextIndex = mLruProcessServiceStart;
2619            inActivity = true;
2620        } else if (hasService) {
2621            // Process has services, put it at the top of the service list.
2622            addIndex = mLruProcessActivityStart;
2623            nextIndex = mLruProcessServiceStart;
2624            inActivity = true;
2625            inService = true;
2626        } else  {
2627            // Process not otherwise of interest, it goes to the top of the non-service area.
2628            addIndex = mLruProcessServiceStart;
2629            if (client != null) {
2630                int clientIndex = mLruProcesses.lastIndexOf(client);
2631                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2632                        + app);
2633                if (clientIndex >= 0 && addIndex > clientIndex) {
2634                    addIndex = clientIndex;
2635                }
2636            }
2637            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2638        }
2639
2640        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2641                + mLruProcessActivityStart + "): " + app);
2642        */
2643
2644        if (lrui >= 0) {
2645            if (lrui < mLruProcessActivityStart) {
2646                mLruProcessActivityStart--;
2647            }
2648            if (lrui < mLruProcessServiceStart) {
2649                mLruProcessServiceStart--;
2650            }
2651            /*
2652            if (addIndex > lrui) {
2653                addIndex--;
2654            }
2655            if (nextIndex > lrui) {
2656                nextIndex--;
2657            }
2658            */
2659            mLruProcesses.remove(lrui);
2660        }
2661
2662        /*
2663        mLruProcesses.add(addIndex, app);
2664        if (inActivity) {
2665            mLruProcessActivityStart++;
2666        }
2667        if (inService) {
2668            mLruProcessActivityStart++;
2669        }
2670        */
2671
2672        int nextIndex;
2673        if (hasActivity) {
2674            final int N = mLruProcesses.size();
2675            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2676                // Process doesn't have activities, but has clients with
2677                // activities...  move it up, but one below the top (the top
2678                // should always have a real activity).
2679                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2680                mLruProcesses.add(N-1, app);
2681                // To keep it from spamming the LRU list (by making a bunch of clients),
2682                // we will push down any other entries owned by the app.
2683                final int uid = app.info.uid;
2684                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2685                    ProcessRecord subProc = mLruProcesses.get(i);
2686                    if (subProc.info.uid == uid) {
2687                        // We want to push this one down the list.  If the process after
2688                        // it is for the same uid, however, don't do so, because we don't
2689                        // want them internally to be re-ordered.
2690                        if (mLruProcesses.get(i-1).info.uid != uid) {
2691                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2692                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2693                            ProcessRecord tmp = mLruProcesses.get(i);
2694                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2695                            mLruProcesses.set(i-1, tmp);
2696                            i--;
2697                        }
2698                    } else {
2699                        // A gap, we can stop here.
2700                        break;
2701                    }
2702                }
2703            } else {
2704                // Process has activities, put it at the very tipsy-top.
2705                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2706                mLruProcesses.add(app);
2707            }
2708            nextIndex = mLruProcessServiceStart;
2709        } else if (hasService) {
2710            // Process has services, put it at the top of the service list.
2711            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2712            mLruProcesses.add(mLruProcessActivityStart, app);
2713            nextIndex = mLruProcessServiceStart;
2714            mLruProcessActivityStart++;
2715        } else  {
2716            // Process not otherwise of interest, it goes to the top of the non-service area.
2717            int index = mLruProcessServiceStart;
2718            if (client != null) {
2719                // If there is a client, don't allow the process to be moved up higher
2720                // in the list than that client.
2721                int clientIndex = mLruProcesses.lastIndexOf(client);
2722                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2723                        + " when updating " + app);
2724                if (clientIndex <= lrui) {
2725                    // Don't allow the client index restriction to push it down farther in the
2726                    // list than it already is.
2727                    clientIndex = lrui;
2728                }
2729                if (clientIndex >= 0 && index > clientIndex) {
2730                    index = clientIndex;
2731                }
2732            }
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2734            mLruProcesses.add(index, app);
2735            nextIndex = index-1;
2736            mLruProcessActivityStart++;
2737            mLruProcessServiceStart++;
2738        }
2739
2740        // If the app is currently using a content provider or service,
2741        // bump those processes as well.
2742        for (int j=app.connections.size()-1; j>=0; j--) {
2743            ConnectionRecord cr = app.connections.valueAt(j);
2744            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2745                    && cr.binding.service.app != null
2746                    && cr.binding.service.app.lruSeq != mLruSeq
2747                    && !cr.binding.service.app.persistent) {
2748                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2749                        "service connection", cr, app);
2750            }
2751        }
2752        for (int j=app.conProviders.size()-1; j>=0; j--) {
2753            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2754            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2755                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2756                        "provider reference", cpr, app);
2757            }
2758        }
2759    }
2760
2761    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2762        if (uid == Process.SYSTEM_UID) {
2763            // The system gets to run in any process.  If there are multiple
2764            // processes with the same uid, just pick the first (this
2765            // should never happen).
2766            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2767            if (procs == null) return null;
2768            final int N = procs.size();
2769            for (int i = 0; i < N; i++) {
2770                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2771            }
2772        }
2773        ProcessRecord proc = mProcessNames.get(processName, uid);
2774        if (false && proc != null && !keepIfLarge
2775                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2776                && proc.lastCachedPss >= 4000) {
2777            // Turn this condition on to cause killing to happen regularly, for testing.
2778            if (proc.baseProcessTracker != null) {
2779                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2780            }
2781            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2782                    + "k from cached");
2783        } else if (proc != null && !keepIfLarge
2784                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2785                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2786            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2787            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2788                if (proc.baseProcessTracker != null) {
2789                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2790                }
2791                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2792                        + "k from cached");
2793            }
2794        }
2795        return proc;
2796    }
2797
2798    void ensurePackageDexOpt(String packageName) {
2799        IPackageManager pm = AppGlobals.getPackageManager();
2800        try {
2801            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2802                mDidDexOpt = true;
2803            }
2804        } catch (RemoteException e) {
2805        }
2806    }
2807
2808    boolean isNextTransitionForward() {
2809        int transit = mWindowManager.getPendingAppTransition();
2810        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2811                || transit == AppTransition.TRANSIT_TASK_OPEN
2812                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2813    }
2814
2815    final ProcessRecord startProcessLocked(String processName,
2816            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2817            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2818            boolean isolated, boolean keepIfLarge) {
2819        ProcessRecord app;
2820        if (!isolated) {
2821            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2822        } else {
2823            // If this is an isolated process, it can't re-use an existing process.
2824            app = null;
2825        }
2826        // We don't have to do anything more if:
2827        // (1) There is an existing application record; and
2828        // (2) The caller doesn't think it is dead, OR there is no thread
2829        //     object attached to it so we know it couldn't have crashed; and
2830        // (3) There is a pid assigned to it, so it is either starting or
2831        //     already running.
2832        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2833                + " app=" + app + " knownToBeDead=" + knownToBeDead
2834                + " thread=" + (app != null ? app.thread : null)
2835                + " pid=" + (app != null ? app.pid : -1));
2836        if (app != null && app.pid > 0) {
2837            if (!knownToBeDead || app.thread == null) {
2838                // We already have the app running, or are waiting for it to
2839                // come up (we have a pid but not yet its thread), so keep it.
2840                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2841                // If this is a new package in the process, add the package to the list
2842                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2843                return app;
2844            }
2845
2846            // An application record is attached to a previous process,
2847            // clean it up now.
2848            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2849            Process.killProcessGroup(app.info.uid, app.pid);
2850            handleAppDiedLocked(app, true, true);
2851        }
2852
2853        String hostingNameStr = hostingName != null
2854                ? hostingName.flattenToShortString() : null;
2855
2856        if (!isolated) {
2857            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2858                // If we are in the background, then check to see if this process
2859                // is bad.  If so, we will just silently fail.
2860                if (mBadProcesses.get(info.processName, info.uid) != null) {
2861                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2862                            + "/" + info.processName);
2863                    return null;
2864                }
2865            } else {
2866                // When the user is explicitly starting a process, then clear its
2867                // crash count so that we won't make it bad until they see at
2868                // least one crash dialog again, and make the process good again
2869                // if it had been bad.
2870                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2871                        + "/" + info.processName);
2872                mProcessCrashTimes.remove(info.processName, info.uid);
2873                if (mBadProcesses.get(info.processName, info.uid) != null) {
2874                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2875                            UserHandle.getUserId(info.uid), info.uid,
2876                            info.processName);
2877                    mBadProcesses.remove(info.processName, info.uid);
2878                    if (app != null) {
2879                        app.bad = false;
2880                    }
2881                }
2882            }
2883        }
2884
2885        if (app == null) {
2886            app = newProcessRecordLocked(info, processName, isolated);
2887            if (app == null) {
2888                Slog.w(TAG, "Failed making new process record for "
2889                        + processName + "/" + info.uid + " isolated=" + isolated);
2890                return null;
2891            }
2892            mProcessNames.put(processName, app.uid, app);
2893            if (isolated) {
2894                mIsolatedProcesses.put(app.uid, app);
2895            }
2896        } else {
2897            // If this is a new package in the process, add the package to the list
2898            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899        }
2900
2901        // If the system is not ready yet, then hold off on starting this
2902        // process until it is.
2903        if (!mProcessesReady
2904                && !isAllowedWhileBooting(info)
2905                && !allowWhileBooting) {
2906            if (!mProcessesOnHold.contains(app)) {
2907                mProcessesOnHold.add(app);
2908            }
2909            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2910            return app;
2911        }
2912
2913        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2914        return (app.pid != 0) ? app : null;
2915    }
2916
2917    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2918        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2919    }
2920
2921    private final void startProcessLocked(ProcessRecord app,
2922            String hostingType, String hostingNameStr, String abiOverride) {
2923        if (app.pid > 0 && app.pid != MY_PID) {
2924            synchronized (mPidsSelfLocked) {
2925                mPidsSelfLocked.remove(app.pid);
2926                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2927            }
2928            app.setPid(0);
2929        }
2930
2931        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2932                "startProcessLocked removing on hold: " + app);
2933        mProcessesOnHold.remove(app);
2934
2935        updateCpuStats();
2936
2937        try {
2938            int uid = app.uid;
2939
2940            int[] gids = null;
2941            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2942            if (!app.isolated) {
2943                int[] permGids = null;
2944                try {
2945                    final PackageManager pm = mContext.getPackageManager();
2946                    permGids = pm.getPackageGids(app.info.packageName);
2947
2948                    if (Environment.isExternalStorageEmulated()) {
2949                        if (pm.checkPermission(
2950                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2951                                app.info.packageName) == PERMISSION_GRANTED) {
2952                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2953                        } else {
2954                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2955                        }
2956                    }
2957                } catch (PackageManager.NameNotFoundException e) {
2958                    Slog.w(TAG, "Unable to retrieve gids", e);
2959                }
2960
2961                /*
2962                 * Add shared application and profile GIDs so applications can share some
2963                 * resources like shared libraries and access user-wide resources
2964                 */
2965                if (permGids == null) {
2966                    gids = new int[2];
2967                } else {
2968                    gids = new int[permGids.length + 2];
2969                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2970                }
2971                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2972                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2973            }
2974            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2975                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2976                        && mTopComponent != null
2977                        && app.processName.equals(mTopComponent.getPackageName())) {
2978                    uid = 0;
2979                }
2980                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2981                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2982                    uid = 0;
2983                }
2984            }
2985            int debugFlags = 0;
2986            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2988                // Also turn on CheckJNI for debuggable apps. It's quite
2989                // awkward to turn on otherwise.
2990                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2991            }
2992            // Run the app in safe mode if its manifest requests so or the
2993            // system is booted in safe mode.
2994            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2995                mSafeMode == true) {
2996                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2997            }
2998            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3000            }
3001            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3002                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3003            }
3004            if ("1".equals(SystemProperties.get("debug.assert"))) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3006            }
3007
3008            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3009            if (requiredAbi == null) {
3010                requiredAbi = Build.SUPPORTED_ABIS[0];
3011            }
3012
3013            // Start the process.  It will either succeed and return a result containing
3014            // the PID of the new process, or else throw a RuntimeException.
3015            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3016                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3017                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3018
3019            if (app.isolated) {
3020                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3021            }
3022            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3023
3024            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3025                    UserHandle.getUserId(uid), startResult.pid, uid,
3026                    app.processName, hostingType,
3027                    hostingNameStr != null ? hostingNameStr : "");
3028
3029            if (app.persistent) {
3030                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3031            }
3032
3033            StringBuilder buf = mStringBuilder;
3034            buf.setLength(0);
3035            buf.append("Start proc ");
3036            buf.append(app.processName);
3037            buf.append(" for ");
3038            buf.append(hostingType);
3039            if (hostingNameStr != null) {
3040                buf.append(" ");
3041                buf.append(hostingNameStr);
3042            }
3043            buf.append(": pid=");
3044            buf.append(startResult.pid);
3045            buf.append(" uid=");
3046            buf.append(uid);
3047            buf.append(" gids={");
3048            if (gids != null) {
3049                for (int gi=0; gi<gids.length; gi++) {
3050                    if (gi != 0) buf.append(", ");
3051                    buf.append(gids[gi]);
3052
3053                }
3054            }
3055            buf.append("}");
3056            if (requiredAbi != null) {
3057                buf.append(" abi=");
3058                buf.append(requiredAbi);
3059            }
3060            Slog.i(TAG, buf.toString());
3061            app.setPid(startResult.pid);
3062            app.usingWrapper = startResult.usingWrapper;
3063            app.removed = false;
3064            app.killedByAm = false;
3065            synchronized (mPidsSelfLocked) {
3066                this.mPidsSelfLocked.put(startResult.pid, app);
3067                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3068                msg.obj = app;
3069                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3070                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3071            }
3072        } catch (RuntimeException e) {
3073            // XXX do better error recovery.
3074            app.setPid(0);
3075            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3076            if (app.isolated) {
3077                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3078            }
3079            Slog.e(TAG, "Failure starting process " + app.processName, e);
3080        }
3081    }
3082
3083    void updateUsageStats(ActivityRecord component, boolean resumed) {
3084        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3085        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3086        if (resumed) {
3087            if (mUsageStatsService != null) {
3088                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3089                        UsageStats.Event.MOVE_TO_FOREGROUND);
3090            }
3091            synchronized (stats) {
3092                stats.noteActivityResumedLocked(component.app.uid);
3093            }
3094        } else {
3095            if (mUsageStatsService != null) {
3096                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3097                        UsageStats.Event.MOVE_TO_BACKGROUND);
3098            }
3099            synchronized (stats) {
3100                stats.noteActivityPausedLocked(component.app.uid);
3101            }
3102        }
3103    }
3104
3105    Intent getHomeIntent() {
3106        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3107        intent.setComponent(mTopComponent);
3108        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3109            intent.addCategory(Intent.CATEGORY_HOME);
3110        }
3111        return intent;
3112    }
3113
3114    boolean startHomeActivityLocked(int userId) {
3115        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3116                && mTopAction == null) {
3117            // We are running in factory test mode, but unable to find
3118            // the factory test app, so just sit around displaying the
3119            // error message and don't try to start anything.
3120            return false;
3121        }
3122        Intent intent = getHomeIntent();
3123        ActivityInfo aInfo =
3124            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3125        if (aInfo != null) {
3126            intent.setComponent(new ComponentName(
3127                    aInfo.applicationInfo.packageName, aInfo.name));
3128            // Don't do this if the home app is currently being
3129            // instrumented.
3130            aInfo = new ActivityInfo(aInfo);
3131            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3132            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3133                    aInfo.applicationInfo.uid, true);
3134            if (app == null || app.instrumentationClass == null) {
3135                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3136                mStackSupervisor.startHomeActivity(intent, aInfo);
3137            }
3138        }
3139
3140        return true;
3141    }
3142
3143    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3144        ActivityInfo ai = null;
3145        ComponentName comp = intent.getComponent();
3146        try {
3147            if (comp != null) {
3148                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3149            } else {
3150                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3151                        intent,
3152                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3153                            flags, userId);
3154
3155                if (info != null) {
3156                    ai = info.activityInfo;
3157                }
3158            }
3159        } catch (RemoteException e) {
3160            // ignore
3161        }
3162
3163        return ai;
3164    }
3165
3166    /**
3167     * Starts the "new version setup screen" if appropriate.
3168     */
3169    void startSetupActivityLocked() {
3170        // Only do this once per boot.
3171        if (mCheckedForSetup) {
3172            return;
3173        }
3174
3175        // We will show this screen if the current one is a different
3176        // version than the last one shown, and we are not running in
3177        // low-level factory test mode.
3178        final ContentResolver resolver = mContext.getContentResolver();
3179        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3180                Settings.Global.getInt(resolver,
3181                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3182            mCheckedForSetup = true;
3183
3184            // See if we should be showing the platform update setup UI.
3185            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3186            List<ResolveInfo> ris = mContext.getPackageManager()
3187                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3188
3189            // We don't allow third party apps to replace this.
3190            ResolveInfo ri = null;
3191            for (int i=0; ris != null && i<ris.size(); i++) {
3192                if ((ris.get(i).activityInfo.applicationInfo.flags
3193                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3194                    ri = ris.get(i);
3195                    break;
3196                }
3197            }
3198
3199            if (ri != null) {
3200                String vers = ri.activityInfo.metaData != null
3201                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3202                        : null;
3203                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3204                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3205                            Intent.METADATA_SETUP_VERSION);
3206                }
3207                String lastVers = Settings.Secure.getString(
3208                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3209                if (vers != null && !vers.equals(lastVers)) {
3210                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3211                    intent.setComponent(new ComponentName(
3212                            ri.activityInfo.packageName, ri.activityInfo.name));
3213                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3214                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3215                }
3216            }
3217        }
3218    }
3219
3220    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3221        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3222    }
3223
3224    void enforceNotIsolatedCaller(String caller) {
3225        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3226            throw new SecurityException("Isolated process not allowed to call " + caller);
3227        }
3228    }
3229
3230    @Override
3231    public int getFrontActivityScreenCompatMode() {
3232        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3233        synchronized (this) {
3234            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3235        }
3236    }
3237
3238    @Override
3239    public void setFrontActivityScreenCompatMode(int mode) {
3240        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3241                "setFrontActivityScreenCompatMode");
3242        synchronized (this) {
3243            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3244        }
3245    }
3246
3247    @Override
3248    public int getPackageScreenCompatMode(String packageName) {
3249        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3250        synchronized (this) {
3251            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3252        }
3253    }
3254
3255    @Override
3256    public void setPackageScreenCompatMode(String packageName, int mode) {
3257        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3258                "setPackageScreenCompatMode");
3259        synchronized (this) {
3260            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3261        }
3262    }
3263
3264    @Override
3265    public boolean getPackageAskScreenCompat(String packageName) {
3266        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3267        synchronized (this) {
3268            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3269        }
3270    }
3271
3272    @Override
3273    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3274        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3275                "setPackageAskScreenCompat");
3276        synchronized (this) {
3277            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3278        }
3279    }
3280
3281    private void dispatchProcessesChanged() {
3282        int N;
3283        synchronized (this) {
3284            N = mPendingProcessChanges.size();
3285            if (mActiveProcessChanges.length < N) {
3286                mActiveProcessChanges = new ProcessChangeItem[N];
3287            }
3288            mPendingProcessChanges.toArray(mActiveProcessChanges);
3289            mAvailProcessChanges.addAll(mPendingProcessChanges);
3290            mPendingProcessChanges.clear();
3291            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3292        }
3293
3294        int i = mProcessObservers.beginBroadcast();
3295        while (i > 0) {
3296            i--;
3297            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3298            if (observer != null) {
3299                try {
3300                    for (int j=0; j<N; j++) {
3301                        ProcessChangeItem item = mActiveProcessChanges[j];
3302                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3303                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3304                                    + item.pid + " uid=" + item.uid + ": "
3305                                    + item.foregroundActivities);
3306                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3307                                    item.foregroundActivities);
3308                        }
3309                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3310                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3311                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3312                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3313                        }
3314                    }
3315                } catch (RemoteException e) {
3316                }
3317            }
3318        }
3319        mProcessObservers.finishBroadcast();
3320    }
3321
3322    private void dispatchProcessDied(int pid, int uid) {
3323        int i = mProcessObservers.beginBroadcast();
3324        while (i > 0) {
3325            i--;
3326            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3327            if (observer != null) {
3328                try {
3329                    observer.onProcessDied(pid, uid);
3330                } catch (RemoteException e) {
3331                }
3332            }
3333        }
3334        mProcessObservers.finishBroadcast();
3335    }
3336
3337    @Override
3338    public final int startActivity(IApplicationThread caller, String callingPackage,
3339            Intent intent, String resolvedType, IBinder resultTo,
3340            String resultWho, int requestCode, int startFlags,
3341            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3342        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3343                resultWho, requestCode,
3344                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3345    }
3346
3347    @Override
3348    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3349            Intent intent, String resolvedType, IBinder resultTo,
3350            String resultWho, int requestCode, int startFlags,
3351            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3352        enforceNotIsolatedCaller("startActivity");
3353        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3354                false, ALLOW_FULL_ONLY, "startActivity", null);
3355        // TODO: Switch to user app stacks here.
3356        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3357                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3358                null, null, options, userId, null);
3359    }
3360
3361    @Override
3362    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3363            Intent intent, String resolvedType, IBinder resultTo,
3364            String resultWho, int requestCode, int startFlags, String profileFile,
3365            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivityAndWait");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3369        WaitResult res = new WaitResult();
3370        // TODO: Switch to user app stacks here.
3371        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3372                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3373                res, null, options, userId, null);
3374        return res;
3375    }
3376
3377    @Override
3378    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3379            Intent intent, String resolvedType, IBinder resultTo,
3380            String resultWho, int requestCode, int startFlags, Configuration config,
3381            Bundle options, int userId) {
3382        enforceNotIsolatedCaller("startActivityWithConfig");
3383        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3384                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3385        // TODO: Switch to user app stacks here.
3386        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3387                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3388                null, null, null, config, options, userId, null);
3389        return ret;
3390    }
3391
3392    @Override
3393    public int startActivityIntentSender(IApplicationThread caller,
3394            IntentSender intent, Intent fillInIntent, String resolvedType,
3395            IBinder resultTo, String resultWho, int requestCode,
3396            int flagsMask, int flagsValues, Bundle options) {
3397        enforceNotIsolatedCaller("startActivityIntentSender");
3398        // Refuse possible leaked file descriptors
3399        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3400            throw new IllegalArgumentException("File descriptors passed in Intent");
3401        }
3402
3403        IIntentSender sender = intent.getTarget();
3404        if (!(sender instanceof PendingIntentRecord)) {
3405            throw new IllegalArgumentException("Bad PendingIntent object");
3406        }
3407
3408        PendingIntentRecord pir = (PendingIntentRecord)sender;
3409
3410        synchronized (this) {
3411            // If this is coming from the currently resumed activity, it is
3412            // effectively saying that app switches are allowed at this point.
3413            final ActivityStack stack = getFocusedStack();
3414            if (stack.mResumedActivity != null &&
3415                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3416                mAppSwitchesAllowedTime = 0;
3417            }
3418        }
3419        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3420                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3421        return ret;
3422    }
3423
3424    @Override
3425    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3426            Intent intent, String resolvedType, IVoiceInteractionSession session,
3427            IVoiceInteractor interactor, int startFlags, String profileFile,
3428            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3429        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3430                != PackageManager.PERMISSION_GRANTED) {
3431            String msg = "Permission Denial: startVoiceActivity() from pid="
3432                    + Binder.getCallingPid()
3433                    + ", uid=" + Binder.getCallingUid()
3434                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3435            Slog.w(TAG, msg);
3436            throw new SecurityException(msg);
3437        }
3438        if (session == null || interactor == null) {
3439            throw new NullPointerException("null session or interactor");
3440        }
3441        userId = handleIncomingUser(callingPid, callingUid, userId,
3442                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3443        // TODO: Switch to user app stacks here.
3444        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3445                resolvedType, session, interactor, null, null, 0, startFlags,
3446                profileFile, profileFd, null, null, options, userId, null);
3447    }
3448
3449    @Override
3450    public boolean startNextMatchingActivity(IBinder callingActivity,
3451            Intent intent, Bundle options) {
3452        // Refuse possible leaked file descriptors
3453        if (intent != null && intent.hasFileDescriptors() == true) {
3454            throw new IllegalArgumentException("File descriptors passed in Intent");
3455        }
3456
3457        synchronized (this) {
3458            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3459            if (r == null) {
3460                ActivityOptions.abort(options);
3461                return false;
3462            }
3463            if (r.app == null || r.app.thread == null) {
3464                // The caller is not running...  d'oh!
3465                ActivityOptions.abort(options);
3466                return false;
3467            }
3468            intent = new Intent(intent);
3469            // The caller is not allowed to change the data.
3470            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3471            // And we are resetting to find the next component...
3472            intent.setComponent(null);
3473
3474            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3475
3476            ActivityInfo aInfo = null;
3477            try {
3478                List<ResolveInfo> resolves =
3479                    AppGlobals.getPackageManager().queryIntentActivities(
3480                            intent, r.resolvedType,
3481                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3482                            UserHandle.getCallingUserId());
3483
3484                // Look for the original activity in the list...
3485                final int N = resolves != null ? resolves.size() : 0;
3486                for (int i=0; i<N; i++) {
3487                    ResolveInfo rInfo = resolves.get(i);
3488                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3489                            && rInfo.activityInfo.name.equals(r.info.name)) {
3490                        // We found the current one...  the next matching is
3491                        // after it.
3492                        i++;
3493                        if (i<N) {
3494                            aInfo = resolves.get(i).activityInfo;
3495                        }
3496                        if (debug) {
3497                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3498                                    + "/" + r.info.name);
3499                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3500                                    + "/" + aInfo.name);
3501                        }
3502                        break;
3503                    }
3504                }
3505            } catch (RemoteException e) {
3506            }
3507
3508            if (aInfo == null) {
3509                // Nobody who is next!
3510                ActivityOptions.abort(options);
3511                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3512                return false;
3513            }
3514
3515            intent.setComponent(new ComponentName(
3516                    aInfo.applicationInfo.packageName, aInfo.name));
3517            intent.setFlags(intent.getFlags()&~(
3518                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3519                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3520                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3521                    Intent.FLAG_ACTIVITY_NEW_TASK));
3522
3523            // Okay now we need to start the new activity, replacing the
3524            // currently running activity.  This is a little tricky because
3525            // we want to start the new one as if the current one is finished,
3526            // but not finish the current one first so that there is no flicker.
3527            // And thus...
3528            final boolean wasFinishing = r.finishing;
3529            r.finishing = true;
3530
3531            // Propagate reply information over to the new activity.
3532            final ActivityRecord resultTo = r.resultTo;
3533            final String resultWho = r.resultWho;
3534            final int requestCode = r.requestCode;
3535            r.resultTo = null;
3536            if (resultTo != null) {
3537                resultTo.removeResultsLocked(r, resultWho, requestCode);
3538            }
3539
3540            final long origId = Binder.clearCallingIdentity();
3541            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3542                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3543                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3544                    options, false, null, null);
3545            Binder.restoreCallingIdentity(origId);
3546
3547            r.finishing = wasFinishing;
3548            if (res != ActivityManager.START_SUCCESS) {
3549                return false;
3550            }
3551            return true;
3552        }
3553    }
3554
3555    @Override
3556    public final int startActivityFromRecents(int taskId, Bundle options) {
3557        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3558            String msg = "Permission Denial: startActivityFromRecents called without " +
3559                    START_TASKS_FROM_RECENTS;
3560            Slog.w(TAG, msg);
3561            throw new SecurityException(msg);
3562        }
3563        final int callingUid;
3564        final String callingPackage;
3565        final Intent intent;
3566        final int userId;
3567        synchronized (this) {
3568            final TaskRecord task = recentTaskForIdLocked(taskId);
3569            if (task == null) {
3570                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3571            }
3572            callingUid = task.mCallingUid;
3573            callingPackage = task.mCallingPackage;
3574            intent = task.intent;
3575            userId = task.userId;
3576        }
3577        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3578                options, userId, null);
3579    }
3580
3581    final int startActivityInPackage(int uid, String callingPackage,
3582            Intent intent, String resolvedType, IBinder resultTo,
3583            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3584                    IActivityContainer container) {
3585
3586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3587                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3588
3589        // TODO: Switch to user app stacks here.
3590        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3591                null, null, resultTo, resultWho, requestCode, startFlags,
3592                null, null, null, null, options, userId, container);
3593        return ret;
3594    }
3595
3596    @Override
3597    public final int startActivities(IApplicationThread caller, String callingPackage,
3598            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3599            int userId) {
3600        enforceNotIsolatedCaller("startActivities");
3601        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3602                false, ALLOW_FULL_ONLY, "startActivity", null);
3603        // TODO: Switch to user app stacks here.
3604        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3605                resolvedTypes, resultTo, options, userId);
3606        return ret;
3607    }
3608
3609    final int startActivitiesInPackage(int uid, String callingPackage,
3610            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3611            Bundle options, int userId) {
3612
3613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3614                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3615        // TODO: Switch to user app stacks here.
3616        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3617                resultTo, options, userId);
3618        return ret;
3619    }
3620
3621    final void addRecentTaskLocked(TaskRecord task) {
3622        int N = mRecentTasks.size();
3623        // Quick case: check if the top-most recent task is the same.
3624        if (N > 0 && mRecentTasks.get(0) == task) {
3625            return;
3626        }
3627        // Another quick case: never add voice sessions.
3628        if (task.voiceSession != null) {
3629            return;
3630        }
3631        // Remove any existing entries that are the same kind of task.
3632        final Intent intent = task.intent;
3633        final boolean document = intent != null && intent.isDocument();
3634        final ComponentName comp = intent.getComponent();
3635
3636        int maxRecents = task.maxRecents - 1;
3637        for (int i=0; i<N; i++) {
3638            final TaskRecord tr = mRecentTasks.get(i);
3639            if (task != tr) {
3640                if (task.userId != tr.userId) {
3641                    continue;
3642                }
3643                if (i > MAX_RECENT_BITMAPS) {
3644                    tr.freeLastThumbnail();
3645                }
3646                final Intent trIntent = tr.intent;
3647                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3648                    (intent == null || !intent.filterEquals(trIntent))) {
3649                    continue;
3650                }
3651                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3652                if (document && trIsDocument) {
3653                    // These are the same document activity (not necessarily the same doc).
3654                    if (maxRecents > 0) {
3655                        --maxRecents;
3656                        continue;
3657                    }
3658                    // Hit the maximum number of documents for this task. Fall through
3659                    // and remove this document from recents.
3660                } else if (document || trIsDocument) {
3661                    // Only one of these is a document. Not the droid we're looking for.
3662                    continue;
3663                }
3664            }
3665
3666            // Either task and tr are the same or, their affinities match or their intents match
3667            // and neither of them is a document, or they are documents using the same activity
3668            // and their maxRecents has been reached.
3669            tr.disposeThumbnail();
3670            mRecentTasks.remove(i);
3671            if (task != tr) {
3672                tr.closeRecentsChain();
3673            }
3674            i--;
3675            N--;
3676            if (task.intent == null) {
3677                // If the new recent task we are adding is not fully
3678                // specified, then replace it with the existing recent task.
3679                task = tr;
3680            }
3681            mTaskPersister.notify(tr, false);
3682        }
3683        if (N >= MAX_RECENT_TASKS) {
3684            final TaskRecord tr = mRecentTasks.remove(N - 1);
3685            tr.disposeThumbnail();
3686            tr.closeRecentsChain();
3687        }
3688        mRecentTasks.add(0, task);
3689    }
3690
3691    @Override
3692    public void reportActivityFullyDrawn(IBinder token) {
3693        synchronized (this) {
3694            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3695            if (r == null) {
3696                return;
3697            }
3698            r.reportFullyDrawnLocked();
3699        }
3700    }
3701
3702    @Override
3703    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3704        synchronized (this) {
3705            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3706            if (r == null) {
3707                return;
3708            }
3709            final long origId = Binder.clearCallingIdentity();
3710            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3711            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3712                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3713            if (config != null) {
3714                r.frozenBeforeDestroy = true;
3715                if (!updateConfigurationLocked(config, r, false, false)) {
3716                    mStackSupervisor.resumeTopActivitiesLocked();
3717                }
3718            }
3719            Binder.restoreCallingIdentity(origId);
3720        }
3721    }
3722
3723    @Override
3724    public int getRequestedOrientation(IBinder token) {
3725        synchronized (this) {
3726            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3727            if (r == null) {
3728                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3729            }
3730            return mWindowManager.getAppOrientation(r.appToken);
3731        }
3732    }
3733
3734    /**
3735     * This is the internal entry point for handling Activity.finish().
3736     *
3737     * @param token The Binder token referencing the Activity we want to finish.
3738     * @param resultCode Result code, if any, from this Activity.
3739     * @param resultData Result data (Intent), if any, from this Activity.
3740     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3741     *            the root Activity in the task.
3742     *
3743     * @return Returns true if the activity successfully finished, or false if it is still running.
3744     */
3745    @Override
3746    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3747            boolean finishTask) {
3748        // Refuse possible leaked file descriptors
3749        if (resultData != null && resultData.hasFileDescriptors() == true) {
3750            throw new IllegalArgumentException("File descriptors passed in Intent");
3751        }
3752
3753        synchronized(this) {
3754            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3755            if (r == null) {
3756                return true;
3757            }
3758            // Keep track of the root activity of the task before we finish it
3759            TaskRecord tr = r.task;
3760            ActivityRecord rootR = tr.getRootActivity();
3761            // Do not allow task to finish in Lock Task mode.
3762            if (tr == mStackSupervisor.mLockTaskModeTask) {
3763                if (rootR == r) {
3764                    mStackSupervisor.showLockTaskToast();
3765                    return false;
3766                }
3767            }
3768            if (mController != null) {
3769                // Find the first activity that is not finishing.
3770                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3771                if (next != null) {
3772                    // ask watcher if this is allowed
3773                    boolean resumeOK = true;
3774                    try {
3775                        resumeOK = mController.activityResuming(next.packageName);
3776                    } catch (RemoteException e) {
3777                        mController = null;
3778                        Watchdog.getInstance().setActivityController(null);
3779                    }
3780
3781                    if (!resumeOK) {
3782                        return false;
3783                    }
3784                }
3785            }
3786            final long origId = Binder.clearCallingIdentity();
3787            try {
3788                boolean res;
3789                if (finishTask && r == rootR) {
3790                    // If requested, remove the task that is associated to this activity only if it
3791                    // was the root activity in the task.  The result code and data is ignored because
3792                    // we don't support returning them across task boundaries.
3793                    res = removeTaskByIdLocked(tr.taskId, 0);
3794                } else {
3795                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3796                            resultData, "app-request", true);
3797                }
3798                return res;
3799            } finally {
3800                Binder.restoreCallingIdentity(origId);
3801            }
3802        }
3803    }
3804
3805    @Override
3806    public final void finishHeavyWeightApp() {
3807        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3808                != PackageManager.PERMISSION_GRANTED) {
3809            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3810                    + Binder.getCallingPid()
3811                    + ", uid=" + Binder.getCallingUid()
3812                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3813            Slog.w(TAG, msg);
3814            throw new SecurityException(msg);
3815        }
3816
3817        synchronized(this) {
3818            if (mHeavyWeightProcess == null) {
3819                return;
3820            }
3821
3822            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3823                    mHeavyWeightProcess.activities);
3824            for (int i=0; i<activities.size(); i++) {
3825                ActivityRecord r = activities.get(i);
3826                if (!r.finishing) {
3827                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3828                            null, "finish-heavy", true);
3829                }
3830            }
3831
3832            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3833                    mHeavyWeightProcess.userId, 0));
3834            mHeavyWeightProcess = null;
3835        }
3836    }
3837
3838    @Override
3839    public void crashApplication(int uid, int initialPid, String packageName,
3840            String message) {
3841        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3842                != PackageManager.PERMISSION_GRANTED) {
3843            String msg = "Permission Denial: crashApplication() from pid="
3844                    + Binder.getCallingPid()
3845                    + ", uid=" + Binder.getCallingUid()
3846                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3847            Slog.w(TAG, msg);
3848            throw new SecurityException(msg);
3849        }
3850
3851        synchronized(this) {
3852            ProcessRecord proc = null;
3853
3854            // Figure out which process to kill.  We don't trust that initialPid
3855            // still has any relation to current pids, so must scan through the
3856            // list.
3857            synchronized (mPidsSelfLocked) {
3858                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3859                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3860                    if (p.uid != uid) {
3861                        continue;
3862                    }
3863                    if (p.pid == initialPid) {
3864                        proc = p;
3865                        break;
3866                    }
3867                    if (p.pkgList.containsKey(packageName)) {
3868                        proc = p;
3869                    }
3870                }
3871            }
3872
3873            if (proc == null) {
3874                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3875                        + " initialPid=" + initialPid
3876                        + " packageName=" + packageName);
3877                return;
3878            }
3879
3880            if (proc.thread != null) {
3881                if (proc.pid == Process.myPid()) {
3882                    Log.w(TAG, "crashApplication: trying to crash self!");
3883                    return;
3884                }
3885                long ident = Binder.clearCallingIdentity();
3886                try {
3887                    proc.thread.scheduleCrash(message);
3888                } catch (RemoteException e) {
3889                }
3890                Binder.restoreCallingIdentity(ident);
3891            }
3892        }
3893    }
3894
3895    @Override
3896    public final void finishSubActivity(IBinder token, String resultWho,
3897            int requestCode) {
3898        synchronized(this) {
3899            final long origId = Binder.clearCallingIdentity();
3900            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3901            if (r != null) {
3902                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3903            }
3904            Binder.restoreCallingIdentity(origId);
3905        }
3906    }
3907
3908    @Override
3909    public boolean finishActivityAffinity(IBinder token) {
3910        synchronized(this) {
3911            final long origId = Binder.clearCallingIdentity();
3912            try {
3913                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3914
3915                ActivityRecord rootR = r.task.getRootActivity();
3916                // Do not allow task to finish in Lock Task mode.
3917                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3918                    if (rootR == r) {
3919                        mStackSupervisor.showLockTaskToast();
3920                        return false;
3921                    }
3922                }
3923                boolean res = false;
3924                if (r != null) {
3925                    res = r.task.stack.finishActivityAffinityLocked(r);
3926                }
3927                return res;
3928            } finally {
3929                Binder.restoreCallingIdentity(origId);
3930            }
3931        }
3932    }
3933
3934    @Override
3935    public void finishVoiceTask(IVoiceInteractionSession session) {
3936        synchronized(this) {
3937            final long origId = Binder.clearCallingIdentity();
3938            try {
3939                mStackSupervisor.finishVoiceTask(session);
3940            } finally {
3941                Binder.restoreCallingIdentity(origId);
3942            }
3943        }
3944
3945    }
3946
3947    @Override
3948    public boolean willActivityBeVisible(IBinder token) {
3949        synchronized(this) {
3950            ActivityStack stack = ActivityRecord.getStackLocked(token);
3951            if (stack != null) {
3952                return stack.willActivityBeVisibleLocked(token);
3953            }
3954            return false;
3955        }
3956    }
3957
3958    @Override
3959    public void overridePendingTransition(IBinder token, String packageName,
3960            int enterAnim, int exitAnim) {
3961        synchronized(this) {
3962            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3963            if (self == null) {
3964                return;
3965            }
3966
3967            final long origId = Binder.clearCallingIdentity();
3968
3969            if (self.state == ActivityState.RESUMED
3970                    || self.state == ActivityState.PAUSING) {
3971                mWindowManager.overridePendingAppTransition(packageName,
3972                        enterAnim, exitAnim, null);
3973            }
3974
3975            Binder.restoreCallingIdentity(origId);
3976        }
3977    }
3978
3979    /**
3980     * Main function for removing an existing process from the activity manager
3981     * as a result of that process going away.  Clears out all connections
3982     * to the process.
3983     */
3984    private final void handleAppDiedLocked(ProcessRecord app,
3985            boolean restarting, boolean allowRestart) {
3986        int pid = app.pid;
3987        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3988        if (!restarting) {
3989            removeLruProcessLocked(app);
3990            if (pid > 0) {
3991                ProcessList.remove(pid);
3992            }
3993        }
3994
3995        if (mProfileProc == app) {
3996            clearProfilerLocked();
3997        }
3998
3999        // Remove this application's activities from active lists.
4000        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4001
4002        app.activities.clear();
4003
4004        if (app.instrumentationClass != null) {
4005            Slog.w(TAG, "Crash of app " + app.processName
4006                  + " running instrumentation " + app.instrumentationClass);
4007            Bundle info = new Bundle();
4008            info.putString("shortMsg", "Process crashed.");
4009            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4010        }
4011
4012        if (!restarting) {
4013            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4014                // If there was nothing to resume, and we are not already
4015                // restarting this process, but there is a visible activity that
4016                // is hosted by the process...  then make sure all visible
4017                // activities are running, taking care of restarting this
4018                // process.
4019                if (hasVisibleActivities) {
4020                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4021                }
4022            }
4023        }
4024    }
4025
4026    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4027        IBinder threadBinder = thread.asBinder();
4028        // Find the application record.
4029        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4030            ProcessRecord rec = mLruProcesses.get(i);
4031            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4032                return i;
4033            }
4034        }
4035        return -1;
4036    }
4037
4038    final ProcessRecord getRecordForAppLocked(
4039            IApplicationThread thread) {
4040        if (thread == null) {
4041            return null;
4042        }
4043
4044        int appIndex = getLRURecordIndexForAppLocked(thread);
4045        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4046    }
4047
4048    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4049        // If there are no longer any background processes running,
4050        // and the app that died was not running instrumentation,
4051        // then tell everyone we are now low on memory.
4052        boolean haveBg = false;
4053        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4054            ProcessRecord rec = mLruProcesses.get(i);
4055            if (rec.thread != null
4056                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4057                haveBg = true;
4058                break;
4059            }
4060        }
4061
4062        if (!haveBg) {
4063            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4064            if (doReport) {
4065                long now = SystemClock.uptimeMillis();
4066                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4067                    doReport = false;
4068                } else {
4069                    mLastMemUsageReportTime = now;
4070                }
4071            }
4072            final ArrayList<ProcessMemInfo> memInfos
4073                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4074            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4075            long now = SystemClock.uptimeMillis();
4076            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4077                ProcessRecord rec = mLruProcesses.get(i);
4078                if (rec == dyingProc || rec.thread == null) {
4079                    continue;
4080                }
4081                if (doReport) {
4082                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4083                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4084                }
4085                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4086                    // The low memory report is overriding any current
4087                    // state for a GC request.  Make sure to do
4088                    // heavy/important/visible/foreground processes first.
4089                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4090                        rec.lastRequestedGc = 0;
4091                    } else {
4092                        rec.lastRequestedGc = rec.lastLowMemory;
4093                    }
4094                    rec.reportLowMemory = true;
4095                    rec.lastLowMemory = now;
4096                    mProcessesToGc.remove(rec);
4097                    addProcessToGcListLocked(rec);
4098                }
4099            }
4100            if (doReport) {
4101                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4102                mHandler.sendMessage(msg);
4103            }
4104            scheduleAppGcsLocked();
4105        }
4106    }
4107
4108    final void appDiedLocked(ProcessRecord app, int pid,
4109            IApplicationThread thread) {
4110
4111        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4112        synchronized (stats) {
4113            stats.noteProcessDiedLocked(app.info.uid, pid);
4114        }
4115
4116        Process.killProcessGroup(app.info.uid, pid);
4117
4118        // Clean up already done if the process has been re-started.
4119        if (app.pid == pid && app.thread != null &&
4120                app.thread.asBinder() == thread.asBinder()) {
4121            boolean doLowMem = app.instrumentationClass == null;
4122            boolean doOomAdj = doLowMem;
4123            if (!app.killedByAm) {
4124                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4125                        + ") has died.");
4126                mAllowLowerMemLevel = true;
4127            } else {
4128                // Note that we always want to do oom adj to update our state with the
4129                // new number of procs.
4130                mAllowLowerMemLevel = false;
4131                doLowMem = false;
4132            }
4133            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4134            if (DEBUG_CLEANUP) Slog.v(
4135                TAG, "Dying app: " + app + ", pid: " + pid
4136                + ", thread: " + thread.asBinder());
4137            handleAppDiedLocked(app, false, true);
4138
4139            if (doOomAdj) {
4140                updateOomAdjLocked();
4141            }
4142            if (doLowMem) {
4143                doLowMemReportIfNeededLocked(app);
4144            }
4145        } else if (app.pid != pid) {
4146            // A new process has already been started.
4147            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4148                    + ") has died and restarted (pid " + app.pid + ").");
4149            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4150        } else if (DEBUG_PROCESSES) {
4151            Slog.d(TAG, "Received spurious death notification for thread "
4152                    + thread.asBinder());
4153        }
4154    }
4155
4156    /**
4157     * If a stack trace dump file is configured, dump process stack traces.
4158     * @param clearTraces causes the dump file to be erased prior to the new
4159     *    traces being written, if true; when false, the new traces will be
4160     *    appended to any existing file content.
4161     * @param firstPids of dalvik VM processes to dump stack traces for first
4162     * @param lastPids of dalvik VM processes to dump stack traces for last
4163     * @param nativeProcs optional list of native process names to dump stack crawls
4164     * @return file containing stack traces, or null if no dump file is configured
4165     */
4166    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4167            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4168        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4169        if (tracesPath == null || tracesPath.length() == 0) {
4170            return null;
4171        }
4172
4173        File tracesFile = new File(tracesPath);
4174        try {
4175            File tracesDir = tracesFile.getParentFile();
4176            if (!tracesDir.exists()) {
4177                tracesFile.mkdirs();
4178                if (!SELinux.restorecon(tracesDir)) {
4179                    return null;
4180                }
4181            }
4182            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4183
4184            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4185            tracesFile.createNewFile();
4186            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4187        } catch (IOException e) {
4188            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4189            return null;
4190        }
4191
4192        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4193        return tracesFile;
4194    }
4195
4196    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4197            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4198        // Use a FileObserver to detect when traces finish writing.
4199        // The order of traces is considered important to maintain for legibility.
4200        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4201            @Override
4202            public synchronized void onEvent(int event, String path) { notify(); }
4203        };
4204
4205        try {
4206            observer.startWatching();
4207
4208            // First collect all of the stacks of the most important pids.
4209            if (firstPids != null) {
4210                try {
4211                    int num = firstPids.size();
4212                    for (int i = 0; i < num; i++) {
4213                        synchronized (observer) {
4214                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4215                            observer.wait(200);  // Wait for write-close, give up after 200msec
4216                        }
4217                    }
4218                } catch (InterruptedException e) {
4219                    Log.wtf(TAG, e);
4220                }
4221            }
4222
4223            // Next collect the stacks of the native pids
4224            if (nativeProcs != null) {
4225                int[] pids = Process.getPidsForCommands(nativeProcs);
4226                if (pids != null) {
4227                    for (int pid : pids) {
4228                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4229                    }
4230                }
4231            }
4232
4233            // Lastly, measure CPU usage.
4234            if (processCpuTracker != null) {
4235                processCpuTracker.init();
4236                System.gc();
4237                processCpuTracker.update();
4238                try {
4239                    synchronized (processCpuTracker) {
4240                        processCpuTracker.wait(500); // measure over 1/2 second.
4241                    }
4242                } catch (InterruptedException e) {
4243                }
4244                processCpuTracker.update();
4245
4246                // We'll take the stack crawls of just the top apps using CPU.
4247                final int N = processCpuTracker.countWorkingStats();
4248                int numProcs = 0;
4249                for (int i=0; i<N && numProcs<5; i++) {
4250                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4251                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4252                        numProcs++;
4253                        try {
4254                            synchronized (observer) {
4255                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4256                                observer.wait(200);  // Wait for write-close, give up after 200msec
4257                            }
4258                        } catch (InterruptedException e) {
4259                            Log.wtf(TAG, e);
4260                        }
4261
4262                    }
4263                }
4264            }
4265        } finally {
4266            observer.stopWatching();
4267        }
4268    }
4269
4270    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4271        if (true || IS_USER_BUILD) {
4272            return;
4273        }
4274        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4275        if (tracesPath == null || tracesPath.length() == 0) {
4276            return;
4277        }
4278
4279        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4280        StrictMode.allowThreadDiskWrites();
4281        try {
4282            final File tracesFile = new File(tracesPath);
4283            final File tracesDir = tracesFile.getParentFile();
4284            final File tracesTmp = new File(tracesDir, "__tmp__");
4285            try {
4286                if (!tracesDir.exists()) {
4287                    tracesFile.mkdirs();
4288                    if (!SELinux.restorecon(tracesDir.getPath())) {
4289                        return;
4290                    }
4291                }
4292                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4293
4294                if (tracesFile.exists()) {
4295                    tracesTmp.delete();
4296                    tracesFile.renameTo(tracesTmp);
4297                }
4298                StringBuilder sb = new StringBuilder();
4299                Time tobj = new Time();
4300                tobj.set(System.currentTimeMillis());
4301                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4302                sb.append(": ");
4303                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4304                sb.append(" since ");
4305                sb.append(msg);
4306                FileOutputStream fos = new FileOutputStream(tracesFile);
4307                fos.write(sb.toString().getBytes());
4308                if (app == null) {
4309                    fos.write("\n*** No application process!".getBytes());
4310                }
4311                fos.close();
4312                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4313            } catch (IOException e) {
4314                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4315                return;
4316            }
4317
4318            if (app != null) {
4319                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4320                firstPids.add(app.pid);
4321                dumpStackTraces(tracesPath, firstPids, null, null, null);
4322            }
4323
4324            File lastTracesFile = null;
4325            File curTracesFile = null;
4326            for (int i=9; i>=0; i--) {
4327                String name = String.format(Locale.US, "slow%02d.txt", i);
4328                curTracesFile = new File(tracesDir, name);
4329                if (curTracesFile.exists()) {
4330                    if (lastTracesFile != null) {
4331                        curTracesFile.renameTo(lastTracesFile);
4332                    } else {
4333                        curTracesFile.delete();
4334                    }
4335                }
4336                lastTracesFile = curTracesFile;
4337            }
4338            tracesFile.renameTo(curTracesFile);
4339            if (tracesTmp.exists()) {
4340                tracesTmp.renameTo(tracesFile);
4341            }
4342        } finally {
4343            StrictMode.setThreadPolicy(oldPolicy);
4344        }
4345    }
4346
4347    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4348            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4349        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4350        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4351
4352        if (mController != null) {
4353            try {
4354                // 0 == continue, -1 = kill process immediately
4355                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4356                if (res < 0 && app.pid != MY_PID) {
4357                    Process.killProcess(app.pid);
4358                    Process.killProcessGroup(app.info.uid, app.pid);
4359                }
4360            } catch (RemoteException e) {
4361                mController = null;
4362                Watchdog.getInstance().setActivityController(null);
4363            }
4364        }
4365
4366        long anrTime = SystemClock.uptimeMillis();
4367        if (MONITOR_CPU_USAGE) {
4368            updateCpuStatsNow();
4369        }
4370
4371        synchronized (this) {
4372            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4373            if (mShuttingDown) {
4374                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4375                return;
4376            } else if (app.notResponding) {
4377                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4378                return;
4379            } else if (app.crashing) {
4380                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4381                return;
4382            }
4383
4384            // In case we come through here for the same app before completing
4385            // this one, mark as anring now so we will bail out.
4386            app.notResponding = true;
4387
4388            // Log the ANR to the event log.
4389            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4390                    app.processName, app.info.flags, annotation);
4391
4392            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4393            firstPids.add(app.pid);
4394
4395            int parentPid = app.pid;
4396            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4397            if (parentPid != app.pid) firstPids.add(parentPid);
4398
4399            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4400
4401            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4402                ProcessRecord r = mLruProcesses.get(i);
4403                if (r != null && r.thread != null) {
4404                    int pid = r.pid;
4405                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4406                        if (r.persistent) {
4407                            firstPids.add(pid);
4408                        } else {
4409                            lastPids.put(pid, Boolean.TRUE);
4410                        }
4411                    }
4412                }
4413            }
4414        }
4415
4416        // Log the ANR to the main log.
4417        StringBuilder info = new StringBuilder();
4418        info.setLength(0);
4419        info.append("ANR in ").append(app.processName);
4420        if (activity != null && activity.shortComponentName != null) {
4421            info.append(" (").append(activity.shortComponentName).append(")");
4422        }
4423        info.append("\n");
4424        info.append("PID: ").append(app.pid).append("\n");
4425        if (annotation != null) {
4426            info.append("Reason: ").append(annotation).append("\n");
4427        }
4428        if (parent != null && parent != activity) {
4429            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4430        }
4431
4432        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4433
4434        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4435                NATIVE_STACKS_OF_INTEREST);
4436
4437        String cpuInfo = null;
4438        if (MONITOR_CPU_USAGE) {
4439            updateCpuStatsNow();
4440            synchronized (mProcessCpuThread) {
4441                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4442            }
4443            info.append(processCpuTracker.printCurrentLoad());
4444            info.append(cpuInfo);
4445        }
4446
4447        info.append(processCpuTracker.printCurrentState(anrTime));
4448
4449        Slog.e(TAG, info.toString());
4450        if (tracesFile == null) {
4451            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4452            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4453        }
4454
4455        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4456                cpuInfo, tracesFile, null);
4457
4458        if (mController != null) {
4459            try {
4460                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4461                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4462                if (res != 0) {
4463                    if (res < 0 && app.pid != MY_PID) {
4464                        Process.killProcess(app.pid);
4465                        Process.killProcessGroup(app.info.uid, app.pid);
4466                    } else {
4467                        synchronized (this) {
4468                            mServices.scheduleServiceTimeoutLocked(app);
4469                        }
4470                    }
4471                    return;
4472                }
4473            } catch (RemoteException e) {
4474                mController = null;
4475                Watchdog.getInstance().setActivityController(null);
4476            }
4477        }
4478
4479        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4480        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4481                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4482
4483        synchronized (this) {
4484            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4485                killUnneededProcessLocked(app, "background ANR");
4486                return;
4487            }
4488
4489            // Set the app's notResponding state, and look up the errorReportReceiver
4490            makeAppNotRespondingLocked(app,
4491                    activity != null ? activity.shortComponentName : null,
4492                    annotation != null ? "ANR " + annotation : "ANR",
4493                    info.toString());
4494
4495            // Bring up the infamous App Not Responding dialog
4496            Message msg = Message.obtain();
4497            HashMap<String, Object> map = new HashMap<String, Object>();
4498            msg.what = SHOW_NOT_RESPONDING_MSG;
4499            msg.obj = map;
4500            msg.arg1 = aboveSystem ? 1 : 0;
4501            map.put("app", app);
4502            if (activity != null) {
4503                map.put("activity", activity);
4504            }
4505
4506            mHandler.sendMessage(msg);
4507        }
4508    }
4509
4510    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4511        if (!mLaunchWarningShown) {
4512            mLaunchWarningShown = true;
4513            mHandler.post(new Runnable() {
4514                @Override
4515                public void run() {
4516                    synchronized (ActivityManagerService.this) {
4517                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4518                        d.show();
4519                        mHandler.postDelayed(new Runnable() {
4520                            @Override
4521                            public void run() {
4522                                synchronized (ActivityManagerService.this) {
4523                                    d.dismiss();
4524                                    mLaunchWarningShown = false;
4525                                }
4526                            }
4527                        }, 4000);
4528                    }
4529                }
4530            });
4531        }
4532    }
4533
4534    @Override
4535    public boolean clearApplicationUserData(final String packageName,
4536            final IPackageDataObserver observer, int userId) {
4537        enforceNotIsolatedCaller("clearApplicationUserData");
4538        int uid = Binder.getCallingUid();
4539        int pid = Binder.getCallingPid();
4540        userId = handleIncomingUser(pid, uid,
4541                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4542        long callingId = Binder.clearCallingIdentity();
4543        try {
4544            IPackageManager pm = AppGlobals.getPackageManager();
4545            int pkgUid = -1;
4546            synchronized(this) {
4547                try {
4548                    pkgUid = pm.getPackageUid(packageName, userId);
4549                } catch (RemoteException e) {
4550                }
4551                if (pkgUid == -1) {
4552                    Slog.w(TAG, "Invalid packageName: " + packageName);
4553                    if (observer != null) {
4554                        try {
4555                            observer.onRemoveCompleted(packageName, false);
4556                        } catch (RemoteException e) {
4557                            Slog.i(TAG, "Observer no longer exists.");
4558                        }
4559                    }
4560                    return false;
4561                }
4562                if (uid == pkgUid || checkComponentPermission(
4563                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4564                        pid, uid, -1, true)
4565                        == PackageManager.PERMISSION_GRANTED) {
4566                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4567                } else {
4568                    throw new SecurityException("PID " + pid + " does not have permission "
4569                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4570                                    + " of package " + packageName);
4571                }
4572            }
4573
4574            try {
4575                // Clear application user data
4576                pm.clearApplicationUserData(packageName, observer, userId);
4577
4578                // Remove all permissions granted from/to this package
4579                removeUriPermissionsForPackageLocked(packageName, userId, true);
4580
4581                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4582                        Uri.fromParts("package", packageName, null));
4583                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4584                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4585                        null, null, 0, null, null, null, false, false, userId);
4586            } catch (RemoteException e) {
4587            }
4588        } finally {
4589            Binder.restoreCallingIdentity(callingId);
4590        }
4591        return true;
4592    }
4593
4594    @Override
4595    public void killBackgroundProcesses(final String packageName, int userId) {
4596        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4597                != PackageManager.PERMISSION_GRANTED &&
4598                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4599                        != PackageManager.PERMISSION_GRANTED) {
4600            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4601                    + Binder.getCallingPid()
4602                    + ", uid=" + Binder.getCallingUid()
4603                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4604            Slog.w(TAG, msg);
4605            throw new SecurityException(msg);
4606        }
4607
4608        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4609                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4610        long callingId = Binder.clearCallingIdentity();
4611        try {
4612            IPackageManager pm = AppGlobals.getPackageManager();
4613            synchronized(this) {
4614                int appId = -1;
4615                try {
4616                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4617                } catch (RemoteException e) {
4618                }
4619                if (appId == -1) {
4620                    Slog.w(TAG, "Invalid packageName: " + packageName);
4621                    return;
4622                }
4623                killPackageProcessesLocked(packageName, appId, userId,
4624                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4625            }
4626        } finally {
4627            Binder.restoreCallingIdentity(callingId);
4628        }
4629    }
4630
4631    @Override
4632    public void killAllBackgroundProcesses() {
4633        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4634                != PackageManager.PERMISSION_GRANTED) {
4635            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4636                    + Binder.getCallingPid()
4637                    + ", uid=" + Binder.getCallingUid()
4638                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4639            Slog.w(TAG, msg);
4640            throw new SecurityException(msg);
4641        }
4642
4643        long callingId = Binder.clearCallingIdentity();
4644        try {
4645            synchronized(this) {
4646                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4647                final int NP = mProcessNames.getMap().size();
4648                for (int ip=0; ip<NP; ip++) {
4649                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4650                    final int NA = apps.size();
4651                    for (int ia=0; ia<NA; ia++) {
4652                        ProcessRecord app = apps.valueAt(ia);
4653                        if (app.persistent) {
4654                            // we don't kill persistent processes
4655                            continue;
4656                        }
4657                        if (app.removed) {
4658                            procs.add(app);
4659                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4660                            app.removed = true;
4661                            procs.add(app);
4662                        }
4663                    }
4664                }
4665
4666                int N = procs.size();
4667                for (int i=0; i<N; i++) {
4668                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4669                }
4670                mAllowLowerMemLevel = true;
4671                updateOomAdjLocked();
4672                doLowMemReportIfNeededLocked(null);
4673            }
4674        } finally {
4675            Binder.restoreCallingIdentity(callingId);
4676        }
4677    }
4678
4679    @Override
4680    public void forceStopPackage(final String packageName, int userId) {
4681        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4682                != PackageManager.PERMISSION_GRANTED) {
4683            String msg = "Permission Denial: forceStopPackage() from pid="
4684                    + Binder.getCallingPid()
4685                    + ", uid=" + Binder.getCallingUid()
4686                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4687            Slog.w(TAG, msg);
4688            throw new SecurityException(msg);
4689        }
4690        final int callingPid = Binder.getCallingPid();
4691        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4692                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4693        long callingId = Binder.clearCallingIdentity();
4694        try {
4695            IPackageManager pm = AppGlobals.getPackageManager();
4696            synchronized(this) {
4697                int[] users = userId == UserHandle.USER_ALL
4698                        ? getUsersLocked() : new int[] { userId };
4699                for (int user : users) {
4700                    int pkgUid = -1;
4701                    try {
4702                        pkgUid = pm.getPackageUid(packageName, user);
4703                    } catch (RemoteException e) {
4704                    }
4705                    if (pkgUid == -1) {
4706                        Slog.w(TAG, "Invalid packageName: " + packageName);
4707                        continue;
4708                    }
4709                    try {
4710                        pm.setPackageStoppedState(packageName, true, user);
4711                    } catch (RemoteException e) {
4712                    } catch (IllegalArgumentException e) {
4713                        Slog.w(TAG, "Failed trying to unstop package "
4714                                + packageName + ": " + e);
4715                    }
4716                    if (isUserRunningLocked(user, false)) {
4717                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4718                    }
4719                }
4720            }
4721        } finally {
4722            Binder.restoreCallingIdentity(callingId);
4723        }
4724    }
4725
4726    @Override
4727    public void addPackageDependency(String packageName) {
4728        synchronized (this) {
4729            int callingPid = Binder.getCallingPid();
4730            if (callingPid == Process.myPid()) {
4731                //  Yeah, um, no.
4732                Slog.w(TAG, "Can't addPackageDependency on system process");
4733                return;
4734            }
4735            ProcessRecord proc;
4736            synchronized (mPidsSelfLocked) {
4737                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4738            }
4739            if (proc != null) {
4740                if (proc.pkgDeps == null) {
4741                    proc.pkgDeps = new ArraySet<String>(1);
4742                }
4743                proc.pkgDeps.add(packageName);
4744            }
4745        }
4746    }
4747
4748    /*
4749     * The pkg name and app id have to be specified.
4750     */
4751    @Override
4752    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4753        if (pkg == null) {
4754            return;
4755        }
4756        // Make sure the uid is valid.
4757        if (appid < 0) {
4758            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4759            return;
4760        }
4761        int callerUid = Binder.getCallingUid();
4762        // Only the system server can kill an application
4763        if (callerUid == Process.SYSTEM_UID) {
4764            // Post an aysnc message to kill the application
4765            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4766            msg.arg1 = appid;
4767            msg.arg2 = 0;
4768            Bundle bundle = new Bundle();
4769            bundle.putString("pkg", pkg);
4770            bundle.putString("reason", reason);
4771            msg.obj = bundle;
4772            mHandler.sendMessage(msg);
4773        } else {
4774            throw new SecurityException(callerUid + " cannot kill pkg: " +
4775                    pkg);
4776        }
4777    }
4778
4779    @Override
4780    public void closeSystemDialogs(String reason) {
4781        enforceNotIsolatedCaller("closeSystemDialogs");
4782
4783        final int pid = Binder.getCallingPid();
4784        final int uid = Binder.getCallingUid();
4785        final long origId = Binder.clearCallingIdentity();
4786        try {
4787            synchronized (this) {
4788                // Only allow this from foreground processes, so that background
4789                // applications can't abuse it to prevent system UI from being shown.
4790                if (uid >= Process.FIRST_APPLICATION_UID) {
4791                    ProcessRecord proc;
4792                    synchronized (mPidsSelfLocked) {
4793                        proc = mPidsSelfLocked.get(pid);
4794                    }
4795                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4796                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4797                                + " from background process " + proc);
4798                        return;
4799                    }
4800                }
4801                closeSystemDialogsLocked(reason);
4802            }
4803        } finally {
4804            Binder.restoreCallingIdentity(origId);
4805        }
4806    }
4807
4808    void closeSystemDialogsLocked(String reason) {
4809        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4810        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4811                | Intent.FLAG_RECEIVER_FOREGROUND);
4812        if (reason != null) {
4813            intent.putExtra("reason", reason);
4814        }
4815        mWindowManager.closeSystemDialogs(reason);
4816
4817        mStackSupervisor.closeSystemDialogsLocked();
4818
4819        broadcastIntentLocked(null, null, intent, null,
4820                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4821                Process.SYSTEM_UID, UserHandle.USER_ALL);
4822    }
4823
4824    @Override
4825    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4826        enforceNotIsolatedCaller("getProcessMemoryInfo");
4827        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4828        for (int i=pids.length-1; i>=0; i--) {
4829            ProcessRecord proc;
4830            int oomAdj;
4831            synchronized (this) {
4832                synchronized (mPidsSelfLocked) {
4833                    proc = mPidsSelfLocked.get(pids[i]);
4834                    oomAdj = proc != null ? proc.setAdj : 0;
4835                }
4836            }
4837            infos[i] = new Debug.MemoryInfo();
4838            Debug.getMemoryInfo(pids[i], infos[i]);
4839            if (proc != null) {
4840                synchronized (this) {
4841                    if (proc.thread != null && proc.setAdj == oomAdj) {
4842                        // Record this for posterity if the process has been stable.
4843                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4844                                infos[i].getTotalUss(), false, proc.pkgList);
4845                    }
4846                }
4847            }
4848        }
4849        return infos;
4850    }
4851
4852    @Override
4853    public long[] getProcessPss(int[] pids) {
4854        enforceNotIsolatedCaller("getProcessPss");
4855        long[] pss = new long[pids.length];
4856        for (int i=pids.length-1; i>=0; i--) {
4857            ProcessRecord proc;
4858            int oomAdj;
4859            synchronized (this) {
4860                synchronized (mPidsSelfLocked) {
4861                    proc = mPidsSelfLocked.get(pids[i]);
4862                    oomAdj = proc != null ? proc.setAdj : 0;
4863                }
4864            }
4865            long[] tmpUss = new long[1];
4866            pss[i] = Debug.getPss(pids[i], tmpUss);
4867            if (proc != null) {
4868                synchronized (this) {
4869                    if (proc.thread != null && proc.setAdj == oomAdj) {
4870                        // Record this for posterity if the process has been stable.
4871                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4872                    }
4873                }
4874            }
4875        }
4876        return pss;
4877    }
4878
4879    @Override
4880    public void killApplicationProcess(String processName, int uid) {
4881        if (processName == null) {
4882            return;
4883        }
4884
4885        int callerUid = Binder.getCallingUid();
4886        // Only the system server can kill an application
4887        if (callerUid == Process.SYSTEM_UID) {
4888            synchronized (this) {
4889                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4890                if (app != null && app.thread != null) {
4891                    try {
4892                        app.thread.scheduleSuicide();
4893                    } catch (RemoteException e) {
4894                        // If the other end already died, then our work here is done.
4895                    }
4896                } else {
4897                    Slog.w(TAG, "Process/uid not found attempting kill of "
4898                            + processName + " / " + uid);
4899                }
4900            }
4901        } else {
4902            throw new SecurityException(callerUid + " cannot kill app process: " +
4903                    processName);
4904        }
4905    }
4906
4907    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4908        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4909                false, true, false, false, UserHandle.getUserId(uid), reason);
4910        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4911                Uri.fromParts("package", packageName, null));
4912        if (!mProcessesReady) {
4913            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4914                    | Intent.FLAG_RECEIVER_FOREGROUND);
4915        }
4916        intent.putExtra(Intent.EXTRA_UID, uid);
4917        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4918        broadcastIntentLocked(null, null, intent,
4919                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4920                false, false,
4921                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4922    }
4923
4924    private void forceStopUserLocked(int userId, String reason) {
4925        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4926        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4927        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4928                | Intent.FLAG_RECEIVER_FOREGROUND);
4929        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4930        broadcastIntentLocked(null, null, intent,
4931                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4932                false, false,
4933                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4934    }
4935
4936    private final boolean killPackageProcessesLocked(String packageName, int appId,
4937            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4938            boolean doit, boolean evenPersistent, String reason) {
4939        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4940
4941        // Remove all processes this package may have touched: all with the
4942        // same UID (except for the system or root user), and all whose name
4943        // matches the package name.
4944        final int NP = mProcessNames.getMap().size();
4945        for (int ip=0; ip<NP; ip++) {
4946            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4947            final int NA = apps.size();
4948            for (int ia=0; ia<NA; ia++) {
4949                ProcessRecord app = apps.valueAt(ia);
4950                if (app.persistent && !evenPersistent) {
4951                    // we don't kill persistent processes
4952                    continue;
4953                }
4954                if (app.removed) {
4955                    if (doit) {
4956                        procs.add(app);
4957                    }
4958                    continue;
4959                }
4960
4961                // Skip process if it doesn't meet our oom adj requirement.
4962                if (app.setAdj < minOomAdj) {
4963                    continue;
4964                }
4965
4966                // If no package is specified, we call all processes under the
4967                // give user id.
4968                if (packageName == null) {
4969                    if (app.userId != userId) {
4970                        continue;
4971                    }
4972                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4973                        continue;
4974                    }
4975                // Package has been specified, we want to hit all processes
4976                // that match it.  We need to qualify this by the processes
4977                // that are running under the specified app and user ID.
4978                } else {
4979                    final boolean isDep = app.pkgDeps != null
4980                            && app.pkgDeps.contains(packageName);
4981                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4982                        continue;
4983                    }
4984                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4985                        continue;
4986                    }
4987                    if (!app.pkgList.containsKey(packageName) && !isDep) {
4988                        continue;
4989                    }
4990                }
4991
4992                // Process has passed all conditions, kill it!
4993                if (!doit) {
4994                    return true;
4995                }
4996                app.removed = true;
4997                procs.add(app);
4998            }
4999        }
5000
5001        int N = procs.size();
5002        for (int i=0; i<N; i++) {
5003            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5004        }
5005        updateOomAdjLocked();
5006        return N > 0;
5007    }
5008
5009    private final boolean forceStopPackageLocked(String name, int appId,
5010            boolean callerWillRestart, boolean purgeCache, boolean doit,
5011            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5012        int i;
5013        int N;
5014
5015        if (userId == UserHandle.USER_ALL && name == null) {
5016            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5017        }
5018
5019        if (appId < 0 && name != null) {
5020            try {
5021                appId = UserHandle.getAppId(
5022                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5023            } catch (RemoteException e) {
5024            }
5025        }
5026
5027        if (doit) {
5028            if (name != null) {
5029                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5030                        + " user=" + userId + ": " + reason);
5031            } else {
5032                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5033            }
5034
5035            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5036            for (int ip=pmap.size()-1; ip>=0; ip--) {
5037                SparseArray<Long> ba = pmap.valueAt(ip);
5038                for (i=ba.size()-1; i>=0; i--) {
5039                    boolean remove = false;
5040                    final int entUid = ba.keyAt(i);
5041                    if (name != null) {
5042                        if (userId == UserHandle.USER_ALL) {
5043                            if (UserHandle.getAppId(entUid) == appId) {
5044                                remove = true;
5045                            }
5046                        } else {
5047                            if (entUid == UserHandle.getUid(userId, appId)) {
5048                                remove = true;
5049                            }
5050                        }
5051                    } else if (UserHandle.getUserId(entUid) == userId) {
5052                        remove = true;
5053                    }
5054                    if (remove) {
5055                        ba.removeAt(i);
5056                    }
5057                }
5058                if (ba.size() == 0) {
5059                    pmap.removeAt(ip);
5060                }
5061            }
5062        }
5063
5064        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5065                -100, callerWillRestart, true, doit, evenPersistent,
5066                name == null ? ("stop user " + userId) : ("stop " + name));
5067
5068        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5069            if (!doit) {
5070                return true;
5071            }
5072            didSomething = true;
5073        }
5074
5075        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5076            if (!doit) {
5077                return true;
5078            }
5079            didSomething = true;
5080        }
5081
5082        if (name == null) {
5083            // Remove all sticky broadcasts from this user.
5084            mStickyBroadcasts.remove(userId);
5085        }
5086
5087        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5088        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5089                userId, providers)) {
5090            if (!doit) {
5091                return true;
5092            }
5093            didSomething = true;
5094        }
5095        N = providers.size();
5096        for (i=0; i<N; i++) {
5097            removeDyingProviderLocked(null, providers.get(i), true);
5098        }
5099
5100        // Remove transient permissions granted from/to this package/user
5101        removeUriPermissionsForPackageLocked(name, userId, false);
5102
5103        if (name == null || uninstalling) {
5104            // Remove pending intents.  For now we only do this when force
5105            // stopping users, because we have some problems when doing this
5106            // for packages -- app widgets are not currently cleaned up for
5107            // such packages, so they can be left with bad pending intents.
5108            if (mIntentSenderRecords.size() > 0) {
5109                Iterator<WeakReference<PendingIntentRecord>> it
5110                        = mIntentSenderRecords.values().iterator();
5111                while (it.hasNext()) {
5112                    WeakReference<PendingIntentRecord> wpir = it.next();
5113                    if (wpir == null) {
5114                        it.remove();
5115                        continue;
5116                    }
5117                    PendingIntentRecord pir = wpir.get();
5118                    if (pir == null) {
5119                        it.remove();
5120                        continue;
5121                    }
5122                    if (name == null) {
5123                        // Stopping user, remove all objects for the user.
5124                        if (pir.key.userId != userId) {
5125                            // Not the same user, skip it.
5126                            continue;
5127                        }
5128                    } else {
5129                        if (UserHandle.getAppId(pir.uid) != appId) {
5130                            // Different app id, skip it.
5131                            continue;
5132                        }
5133                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5134                            // Different user, skip it.
5135                            continue;
5136                        }
5137                        if (!pir.key.packageName.equals(name)) {
5138                            // Different package, skip it.
5139                            continue;
5140                        }
5141                    }
5142                    if (!doit) {
5143                        return true;
5144                    }
5145                    didSomething = true;
5146                    it.remove();
5147                    pir.canceled = true;
5148                    if (pir.key.activity != null) {
5149                        pir.key.activity.pendingResults.remove(pir.ref);
5150                    }
5151                }
5152            }
5153        }
5154
5155        if (doit) {
5156            if (purgeCache && name != null) {
5157                AttributeCache ac = AttributeCache.instance();
5158                if (ac != null) {
5159                    ac.removePackage(name);
5160                }
5161            }
5162            if (mBooted) {
5163                mStackSupervisor.resumeTopActivitiesLocked();
5164                mStackSupervisor.scheduleIdleLocked();
5165            }
5166        }
5167
5168        return didSomething;
5169    }
5170
5171    private final boolean removeProcessLocked(ProcessRecord app,
5172            boolean callerWillRestart, boolean allowRestart, String reason) {
5173        final String name = app.processName;
5174        final int uid = app.uid;
5175        if (DEBUG_PROCESSES) Slog.d(
5176            TAG, "Force removing proc " + app.toShortString() + " (" + name
5177            + "/" + uid + ")");
5178
5179        mProcessNames.remove(name, uid);
5180        mIsolatedProcesses.remove(app.uid);
5181        if (mHeavyWeightProcess == app) {
5182            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5183                    mHeavyWeightProcess.userId, 0));
5184            mHeavyWeightProcess = null;
5185        }
5186        boolean needRestart = false;
5187        if (app.pid > 0 && app.pid != MY_PID) {
5188            int pid = app.pid;
5189            synchronized (mPidsSelfLocked) {
5190                mPidsSelfLocked.remove(pid);
5191                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5192            }
5193            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5194            if (app.isolated) {
5195                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5196            }
5197            killUnneededProcessLocked(app, reason);
5198            Process.killProcessGroup(app.info.uid, app.pid);
5199            handleAppDiedLocked(app, true, allowRestart);
5200            removeLruProcessLocked(app);
5201
5202            if (app.persistent && !app.isolated) {
5203                if (!callerWillRestart) {
5204                    addAppLocked(app.info, false, null /* ABI override */);
5205                } else {
5206                    needRestart = true;
5207                }
5208            }
5209        } else {
5210            mRemovedProcesses.add(app);
5211        }
5212
5213        return needRestart;
5214    }
5215
5216    private final void processStartTimedOutLocked(ProcessRecord app) {
5217        final int pid = app.pid;
5218        boolean gone = false;
5219        synchronized (mPidsSelfLocked) {
5220            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5221            if (knownApp != null && knownApp.thread == null) {
5222                mPidsSelfLocked.remove(pid);
5223                gone = true;
5224            }
5225        }
5226
5227        if (gone) {
5228            Slog.w(TAG, "Process " + app + " failed to attach");
5229            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5230                    pid, app.uid, app.processName);
5231            mProcessNames.remove(app.processName, app.uid);
5232            mIsolatedProcesses.remove(app.uid);
5233            if (mHeavyWeightProcess == app) {
5234                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5235                        mHeavyWeightProcess.userId, 0));
5236                mHeavyWeightProcess = null;
5237            }
5238            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5239            if (app.isolated) {
5240                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5241            }
5242            // Take care of any launching providers waiting for this process.
5243            checkAppInLaunchingProvidersLocked(app, true);
5244            // Take care of any services that are waiting for the process.
5245            mServices.processStartTimedOutLocked(app);
5246            killUnneededProcessLocked(app, "start timeout");
5247            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5248                Slog.w(TAG, "Unattached app died before backup, skipping");
5249                try {
5250                    IBackupManager bm = IBackupManager.Stub.asInterface(
5251                            ServiceManager.getService(Context.BACKUP_SERVICE));
5252                    bm.agentDisconnected(app.info.packageName);
5253                } catch (RemoteException e) {
5254                    // Can't happen; the backup manager is local
5255                }
5256            }
5257            if (isPendingBroadcastProcessLocked(pid)) {
5258                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5259                skipPendingBroadcastLocked(pid);
5260            }
5261        } else {
5262            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5263        }
5264    }
5265
5266    private final boolean attachApplicationLocked(IApplicationThread thread,
5267            int pid) {
5268
5269        // Find the application record that is being attached...  either via
5270        // the pid if we are running in multiple processes, or just pull the
5271        // next app record if we are emulating process with anonymous threads.
5272        ProcessRecord app;
5273        if (pid != MY_PID && pid >= 0) {
5274            synchronized (mPidsSelfLocked) {
5275                app = mPidsSelfLocked.get(pid);
5276            }
5277        } else {
5278            app = null;
5279        }
5280
5281        if (app == null) {
5282            Slog.w(TAG, "No pending application record for pid " + pid
5283                    + " (IApplicationThread " + thread + "); dropping process");
5284            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5285            if (pid > 0 && pid != MY_PID) {
5286                Process.killProcessQuiet(pid);
5287                //TODO: Process.killProcessGroup(app.info.uid, pid);
5288            } else {
5289                try {
5290                    thread.scheduleExit();
5291                } catch (Exception e) {
5292                    // Ignore exceptions.
5293                }
5294            }
5295            return false;
5296        }
5297
5298        // If this application record is still attached to a previous
5299        // process, clean it up now.
5300        if (app.thread != null) {
5301            handleAppDiedLocked(app, true, true);
5302        }
5303
5304        // Tell the process all about itself.
5305
5306        if (localLOGV) Slog.v(
5307                TAG, "Binding process pid " + pid + " to record " + app);
5308
5309        final String processName = app.processName;
5310        try {
5311            AppDeathRecipient adr = new AppDeathRecipient(
5312                    app, pid, thread);
5313            thread.asBinder().linkToDeath(adr, 0);
5314            app.deathRecipient = adr;
5315        } catch (RemoteException e) {
5316            app.resetPackageList(mProcessStats);
5317            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5318            return false;
5319        }
5320
5321        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5322
5323        app.makeActive(thread, mProcessStats);
5324        app.curAdj = app.setAdj = -100;
5325        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5326        app.forcingToForeground = null;
5327        updateProcessForegroundLocked(app, false, false);
5328        app.hasShownUi = false;
5329        app.debugging = false;
5330        app.cached = false;
5331
5332        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5333
5334        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5335        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5336
5337        if (!normalMode) {
5338            Slog.i(TAG, "Launching preboot mode app: " + app);
5339        }
5340
5341        if (localLOGV) Slog.v(
5342            TAG, "New app record " + app
5343            + " thread=" + thread.asBinder() + " pid=" + pid);
5344        try {
5345            int testMode = IApplicationThread.DEBUG_OFF;
5346            if (mDebugApp != null && mDebugApp.equals(processName)) {
5347                testMode = mWaitForDebugger
5348                    ? IApplicationThread.DEBUG_WAIT
5349                    : IApplicationThread.DEBUG_ON;
5350                app.debugging = true;
5351                if (mDebugTransient) {
5352                    mDebugApp = mOrigDebugApp;
5353                    mWaitForDebugger = mOrigWaitForDebugger;
5354                }
5355            }
5356            String profileFile = app.instrumentationProfileFile;
5357            ParcelFileDescriptor profileFd = null;
5358            boolean profileAutoStop = false;
5359            if (mProfileApp != null && mProfileApp.equals(processName)) {
5360                mProfileProc = app;
5361                profileFile = mProfileFile;
5362                profileFd = mProfileFd;
5363                profileAutoStop = mAutoStopProfiler;
5364            }
5365            boolean enableOpenGlTrace = false;
5366            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5367                enableOpenGlTrace = true;
5368                mOpenGlTraceApp = null;
5369            }
5370
5371            // If the app is being launched for restore or full backup, set it up specially
5372            boolean isRestrictedBackupMode = false;
5373            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5374                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5375                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5376                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5377            }
5378
5379            ensurePackageDexOpt(app.instrumentationInfo != null
5380                    ? app.instrumentationInfo.packageName
5381                    : app.info.packageName);
5382            if (app.instrumentationClass != null) {
5383                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5384            }
5385            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5386                    + processName + " with config " + mConfiguration);
5387            ApplicationInfo appInfo = app.instrumentationInfo != null
5388                    ? app.instrumentationInfo : app.info;
5389            app.compat = compatibilityInfoForPackageLocked(appInfo);
5390            if (profileFd != null) {
5391                profileFd = profileFd.dup();
5392            }
5393            thread.bindApplication(processName, appInfo, providers,
5394                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5395                    app.instrumentationArguments, app.instrumentationWatcher,
5396                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5397                    isRestrictedBackupMode || !normalMode, app.persistent,
5398                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5399                    mCoreSettingsObserver.getCoreSettingsLocked());
5400            updateLruProcessLocked(app, false, null);
5401            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5402        } catch (Exception e) {
5403            // todo: Yikes!  What should we do?  For now we will try to
5404            // start another process, but that could easily get us in
5405            // an infinite loop of restarting processes...
5406            Slog.w(TAG, "Exception thrown during bind!", e);
5407
5408            app.resetPackageList(mProcessStats);
5409            app.unlinkDeathRecipient();
5410            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5411            return false;
5412        }
5413
5414        // Remove this record from the list of starting applications.
5415        mPersistentStartingProcesses.remove(app);
5416        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5417                "Attach application locked removing on hold: " + app);
5418        mProcessesOnHold.remove(app);
5419
5420        boolean badApp = false;
5421        boolean didSomething = false;
5422
5423        // See if the top visible activity is waiting to run in this process...
5424        if (normalMode) {
5425            try {
5426                if (mStackSupervisor.attachApplicationLocked(app)) {
5427                    didSomething = true;
5428                }
5429            } catch (Exception e) {
5430                badApp = true;
5431            }
5432        }
5433
5434        // Find any services that should be running in this process...
5435        if (!badApp) {
5436            try {
5437                didSomething |= mServices.attachApplicationLocked(app, processName);
5438            } catch (Exception e) {
5439                badApp = true;
5440            }
5441        }
5442
5443        // Check if a next-broadcast receiver is in this process...
5444        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5445            try {
5446                didSomething |= sendPendingBroadcastsLocked(app);
5447            } catch (Exception e) {
5448                // If the app died trying to launch the receiver we declare it 'bad'
5449                badApp = true;
5450            }
5451        }
5452
5453        // Check whether the next backup agent is in this process...
5454        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5455            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5456            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5457            try {
5458                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5459                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5460                        mBackupTarget.backupMode);
5461            } catch (Exception e) {
5462                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5463                e.printStackTrace();
5464            }
5465        }
5466
5467        if (badApp) {
5468            // todo: Also need to kill application to deal with all
5469            // kinds of exceptions.
5470            handleAppDiedLocked(app, false, true);
5471            return false;
5472        }
5473
5474        if (!didSomething) {
5475            updateOomAdjLocked();
5476        }
5477
5478        return true;
5479    }
5480
5481    @Override
5482    public final void attachApplication(IApplicationThread thread) {
5483        synchronized (this) {
5484            int callingPid = Binder.getCallingPid();
5485            final long origId = Binder.clearCallingIdentity();
5486            attachApplicationLocked(thread, callingPid);
5487            Binder.restoreCallingIdentity(origId);
5488        }
5489    }
5490
5491    @Override
5492    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5493        final long origId = Binder.clearCallingIdentity();
5494        synchronized (this) {
5495            ActivityStack stack = ActivityRecord.getStackLocked(token);
5496            if (stack != null) {
5497                ActivityRecord r =
5498                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5499                if (stopProfiling) {
5500                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5501                        try {
5502                            mProfileFd.close();
5503                        } catch (IOException e) {
5504                        }
5505                        clearProfilerLocked();
5506                    }
5507                }
5508            }
5509        }
5510        Binder.restoreCallingIdentity(origId);
5511    }
5512
5513    void enableScreenAfterBoot() {
5514        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5515                SystemClock.uptimeMillis());
5516        mWindowManager.enableScreenAfterBoot();
5517
5518        synchronized (this) {
5519            updateEventDispatchingLocked();
5520        }
5521    }
5522
5523    @Override
5524    public void showBootMessage(final CharSequence msg, final boolean always) {
5525        enforceNotIsolatedCaller("showBootMessage");
5526        mWindowManager.showBootMessage(msg, always);
5527    }
5528
5529    @Override
5530    public void dismissKeyguardOnNextActivity() {
5531        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5532        final long token = Binder.clearCallingIdentity();
5533        try {
5534            synchronized (this) {
5535                if (DEBUG_LOCKSCREEN) logLockScreen("");
5536                if (mLockScreenShown) {
5537                    mLockScreenShown = false;
5538                    comeOutOfSleepIfNeededLocked();
5539                }
5540                mStackSupervisor.setDismissKeyguard(true);
5541            }
5542        } finally {
5543            Binder.restoreCallingIdentity(token);
5544        }
5545    }
5546
5547    final void finishBooting() {
5548        // Register receivers to handle package update events
5549        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5550
5551        synchronized (this) {
5552            // Ensure that any processes we had put on hold are now started
5553            // up.
5554            final int NP = mProcessesOnHold.size();
5555            if (NP > 0) {
5556                ArrayList<ProcessRecord> procs =
5557                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5558                for (int ip=0; ip<NP; ip++) {
5559                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5560                            + procs.get(ip));
5561                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5562                }
5563            }
5564
5565            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5566                // Start looking for apps that are abusing wake locks.
5567                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5568                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5569                // Tell anyone interested that we are done booting!
5570                SystemProperties.set("sys.boot_completed", "1");
5571                SystemProperties.set("dev.bootcomplete", "1");
5572                for (int i=0; i<mStartedUsers.size(); i++) {
5573                    UserStartedState uss = mStartedUsers.valueAt(i);
5574                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5575                        uss.mState = UserStartedState.STATE_RUNNING;
5576                        final int userId = mStartedUsers.keyAt(i);
5577                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5578                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5579                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5580                        broadcastIntentLocked(null, null, intent, null,
5581                                new IIntentReceiver.Stub() {
5582                                    @Override
5583                                    public void performReceive(Intent intent, int resultCode,
5584                                            String data, Bundle extras, boolean ordered,
5585                                            boolean sticky, int sendingUser) {
5586                                        synchronized (ActivityManagerService.this) {
5587                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5588                                                    true, false);
5589                                        }
5590                                    }
5591                                },
5592                                0, null, null,
5593                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5594                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5595                                userId);
5596                    }
5597                }
5598                scheduleStartProfilesLocked();
5599            }
5600        }
5601    }
5602
5603    final void ensureBootCompleted() {
5604        boolean booting;
5605        boolean enableScreen;
5606        synchronized (this) {
5607            booting = mBooting;
5608            mBooting = false;
5609            enableScreen = !mBooted;
5610            mBooted = true;
5611        }
5612
5613        if (booting) {
5614            finishBooting();
5615        }
5616
5617        if (enableScreen) {
5618            enableScreenAfterBoot();
5619        }
5620    }
5621
5622    @Override
5623    public final void activityResumed(IBinder token) {
5624        final long origId = Binder.clearCallingIdentity();
5625        synchronized(this) {
5626            ActivityStack stack = ActivityRecord.getStackLocked(token);
5627            if (stack != null) {
5628                ActivityRecord.activityResumedLocked(token);
5629            }
5630        }
5631        Binder.restoreCallingIdentity(origId);
5632    }
5633
5634    @Override
5635    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5636        final long origId = Binder.clearCallingIdentity();
5637        synchronized(this) {
5638            ActivityStack stack = ActivityRecord.getStackLocked(token);
5639            if (stack != null) {
5640                stack.activityPausedLocked(token, false, persistentState);
5641            }
5642        }
5643        Binder.restoreCallingIdentity(origId);
5644    }
5645
5646    @Override
5647    public final void activityStopped(IBinder token, Bundle icicle,
5648            PersistableBundle persistentState, CharSequence description) {
5649        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5650
5651        // Refuse possible leaked file descriptors
5652        if (icicle != null && icicle.hasFileDescriptors()) {
5653            throw new IllegalArgumentException("File descriptors passed in Bundle");
5654        }
5655
5656        final long origId = Binder.clearCallingIdentity();
5657
5658        synchronized (this) {
5659            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5660            if (r != null) {
5661                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5662            }
5663        }
5664
5665        trimApplications();
5666
5667        Binder.restoreCallingIdentity(origId);
5668    }
5669
5670    @Override
5671    public final void activityDestroyed(IBinder token) {
5672        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5673        synchronized (this) {
5674            ActivityStack stack = ActivityRecord.getStackLocked(token);
5675            if (stack != null) {
5676                stack.activityDestroyedLocked(token);
5677            }
5678        }
5679    }
5680
5681    @Override
5682    public final void mediaResourcesReleased(IBinder token) {
5683        final long origId = Binder.clearCallingIdentity();
5684        try {
5685            synchronized (this) {
5686                ActivityStack stack = ActivityRecord.getStackLocked(token);
5687                if (stack != null) {
5688                    stack.mediaResourcesReleased(token);
5689                }
5690            }
5691        } finally {
5692            Binder.restoreCallingIdentity(origId);
5693        }
5694    }
5695
5696    @Override
5697    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5698        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5699    }
5700
5701    @Override
5702    public String getCallingPackage(IBinder token) {
5703        synchronized (this) {
5704            ActivityRecord r = getCallingRecordLocked(token);
5705            return r != null ? r.info.packageName : null;
5706        }
5707    }
5708
5709    @Override
5710    public ComponentName getCallingActivity(IBinder token) {
5711        synchronized (this) {
5712            ActivityRecord r = getCallingRecordLocked(token);
5713            return r != null ? r.intent.getComponent() : null;
5714        }
5715    }
5716
5717    private ActivityRecord getCallingRecordLocked(IBinder token) {
5718        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5719        if (r == null) {
5720            return null;
5721        }
5722        return r.resultTo;
5723    }
5724
5725    @Override
5726    public ComponentName getActivityClassForToken(IBinder token) {
5727        synchronized(this) {
5728            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5729            if (r == null) {
5730                return null;
5731            }
5732            return r.intent.getComponent();
5733        }
5734    }
5735
5736    @Override
5737    public String getPackageForToken(IBinder token) {
5738        synchronized(this) {
5739            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5740            if (r == null) {
5741                return null;
5742            }
5743            return r.packageName;
5744        }
5745    }
5746
5747    @Override
5748    public IIntentSender getIntentSender(int type,
5749            String packageName, IBinder token, String resultWho,
5750            int requestCode, Intent[] intents, String[] resolvedTypes,
5751            int flags, Bundle options, int userId) {
5752        enforceNotIsolatedCaller("getIntentSender");
5753        // Refuse possible leaked file descriptors
5754        if (intents != null) {
5755            if (intents.length < 1) {
5756                throw new IllegalArgumentException("Intents array length must be >= 1");
5757            }
5758            for (int i=0; i<intents.length; i++) {
5759                Intent intent = intents[i];
5760                if (intent != null) {
5761                    if (intent.hasFileDescriptors()) {
5762                        throw new IllegalArgumentException("File descriptors passed in Intent");
5763                    }
5764                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5765                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5766                        throw new IllegalArgumentException(
5767                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5768                    }
5769                    intents[i] = new Intent(intent);
5770                }
5771            }
5772            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5773                throw new IllegalArgumentException(
5774                        "Intent array length does not match resolvedTypes length");
5775            }
5776        }
5777        if (options != null) {
5778            if (options.hasFileDescriptors()) {
5779                throw new IllegalArgumentException("File descriptors passed in options");
5780            }
5781        }
5782
5783        synchronized(this) {
5784            int callingUid = Binder.getCallingUid();
5785            int origUserId = userId;
5786            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5787                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5788                    ALLOW_NON_FULL, "getIntentSender", null);
5789            if (origUserId == UserHandle.USER_CURRENT) {
5790                // We don't want to evaluate this until the pending intent is
5791                // actually executed.  However, we do want to always do the
5792                // security checking for it above.
5793                userId = UserHandle.USER_CURRENT;
5794            }
5795            try {
5796                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5797                    int uid = AppGlobals.getPackageManager()
5798                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5799                    if (!UserHandle.isSameApp(callingUid, uid)) {
5800                        String msg = "Permission Denial: getIntentSender() from pid="
5801                            + Binder.getCallingPid()
5802                            + ", uid=" + Binder.getCallingUid()
5803                            + ", (need uid=" + uid + ")"
5804                            + " is not allowed to send as package " + packageName;
5805                        Slog.w(TAG, msg);
5806                        throw new SecurityException(msg);
5807                    }
5808                }
5809
5810                return getIntentSenderLocked(type, packageName, callingUid, userId,
5811                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5812
5813            } catch (RemoteException e) {
5814                throw new SecurityException(e);
5815            }
5816        }
5817    }
5818
5819    IIntentSender getIntentSenderLocked(int type, String packageName,
5820            int callingUid, int userId, IBinder token, String resultWho,
5821            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5822            Bundle options) {
5823        if (DEBUG_MU)
5824            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5825        ActivityRecord activity = null;
5826        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5827            activity = ActivityRecord.isInStackLocked(token);
5828            if (activity == null) {
5829                return null;
5830            }
5831            if (activity.finishing) {
5832                return null;
5833            }
5834        }
5835
5836        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5837        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5838        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5839        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5840                |PendingIntent.FLAG_UPDATE_CURRENT);
5841
5842        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5843                type, packageName, activity, resultWho,
5844                requestCode, intents, resolvedTypes, flags, options, userId);
5845        WeakReference<PendingIntentRecord> ref;
5846        ref = mIntentSenderRecords.get(key);
5847        PendingIntentRecord rec = ref != null ? ref.get() : null;
5848        if (rec != null) {
5849            if (!cancelCurrent) {
5850                if (updateCurrent) {
5851                    if (rec.key.requestIntent != null) {
5852                        rec.key.requestIntent.replaceExtras(intents != null ?
5853                                intents[intents.length - 1] : null);
5854                    }
5855                    if (intents != null) {
5856                        intents[intents.length-1] = rec.key.requestIntent;
5857                        rec.key.allIntents = intents;
5858                        rec.key.allResolvedTypes = resolvedTypes;
5859                    } else {
5860                        rec.key.allIntents = null;
5861                        rec.key.allResolvedTypes = null;
5862                    }
5863                }
5864                return rec;
5865            }
5866            rec.canceled = true;
5867            mIntentSenderRecords.remove(key);
5868        }
5869        if (noCreate) {
5870            return rec;
5871        }
5872        rec = new PendingIntentRecord(this, key, callingUid);
5873        mIntentSenderRecords.put(key, rec.ref);
5874        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5875            if (activity.pendingResults == null) {
5876                activity.pendingResults
5877                        = new HashSet<WeakReference<PendingIntentRecord>>();
5878            }
5879            activity.pendingResults.add(rec.ref);
5880        }
5881        return rec;
5882    }
5883
5884    @Override
5885    public void cancelIntentSender(IIntentSender sender) {
5886        if (!(sender instanceof PendingIntentRecord)) {
5887            return;
5888        }
5889        synchronized(this) {
5890            PendingIntentRecord rec = (PendingIntentRecord)sender;
5891            try {
5892                int uid = AppGlobals.getPackageManager()
5893                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5894                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5895                    String msg = "Permission Denial: cancelIntentSender() from pid="
5896                        + Binder.getCallingPid()
5897                        + ", uid=" + Binder.getCallingUid()
5898                        + " is not allowed to cancel packges "
5899                        + rec.key.packageName;
5900                    Slog.w(TAG, msg);
5901                    throw new SecurityException(msg);
5902                }
5903            } catch (RemoteException e) {
5904                throw new SecurityException(e);
5905            }
5906            cancelIntentSenderLocked(rec, true);
5907        }
5908    }
5909
5910    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5911        rec.canceled = true;
5912        mIntentSenderRecords.remove(rec.key);
5913        if (cleanActivity && rec.key.activity != null) {
5914            rec.key.activity.pendingResults.remove(rec.ref);
5915        }
5916    }
5917
5918    @Override
5919    public String getPackageForIntentSender(IIntentSender pendingResult) {
5920        if (!(pendingResult instanceof PendingIntentRecord)) {
5921            return null;
5922        }
5923        try {
5924            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5925            return res.key.packageName;
5926        } catch (ClassCastException e) {
5927        }
5928        return null;
5929    }
5930
5931    @Override
5932    public int getUidForIntentSender(IIntentSender sender) {
5933        if (sender instanceof PendingIntentRecord) {
5934            try {
5935                PendingIntentRecord res = (PendingIntentRecord)sender;
5936                return res.uid;
5937            } catch (ClassCastException e) {
5938            }
5939        }
5940        return -1;
5941    }
5942
5943    @Override
5944    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5945        if (!(pendingResult instanceof PendingIntentRecord)) {
5946            return false;
5947        }
5948        try {
5949            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5950            if (res.key.allIntents == null) {
5951                return false;
5952            }
5953            for (int i=0; i<res.key.allIntents.length; i++) {
5954                Intent intent = res.key.allIntents[i];
5955                if (intent.getPackage() != null && intent.getComponent() != null) {
5956                    return false;
5957                }
5958            }
5959            return true;
5960        } catch (ClassCastException e) {
5961        }
5962        return false;
5963    }
5964
5965    @Override
5966    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5967        if (!(pendingResult instanceof PendingIntentRecord)) {
5968            return false;
5969        }
5970        try {
5971            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5972            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5973                return true;
5974            }
5975            return false;
5976        } catch (ClassCastException e) {
5977        }
5978        return false;
5979    }
5980
5981    @Override
5982    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5983        if (!(pendingResult instanceof PendingIntentRecord)) {
5984            return null;
5985        }
5986        try {
5987            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5988            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5989        } catch (ClassCastException e) {
5990        }
5991        return null;
5992    }
5993
5994    @Override
5995    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5996        if (!(pendingResult instanceof PendingIntentRecord)) {
5997            return null;
5998        }
5999        try {
6000            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6001            Intent intent = res.key.requestIntent;
6002            if (intent != null) {
6003                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6004                        || res.lastTagPrefix.equals(prefix))) {
6005                    return res.lastTag;
6006                }
6007                res.lastTagPrefix = prefix;
6008                StringBuilder sb = new StringBuilder(128);
6009                if (prefix != null) {
6010                    sb.append(prefix);
6011                }
6012                if (intent.getAction() != null) {
6013                    sb.append(intent.getAction());
6014                } else if (intent.getComponent() != null) {
6015                    intent.getComponent().appendShortString(sb);
6016                } else {
6017                    sb.append("?");
6018                }
6019                return res.lastTag = sb.toString();
6020            }
6021        } catch (ClassCastException e) {
6022        }
6023        return null;
6024    }
6025
6026    @Override
6027    public void setProcessLimit(int max) {
6028        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6029                "setProcessLimit()");
6030        synchronized (this) {
6031            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6032            mProcessLimitOverride = max;
6033        }
6034        trimApplications();
6035    }
6036
6037    @Override
6038    public int getProcessLimit() {
6039        synchronized (this) {
6040            return mProcessLimitOverride;
6041        }
6042    }
6043
6044    void foregroundTokenDied(ForegroundToken token) {
6045        synchronized (ActivityManagerService.this) {
6046            synchronized (mPidsSelfLocked) {
6047                ForegroundToken cur
6048                    = mForegroundProcesses.get(token.pid);
6049                if (cur != token) {
6050                    return;
6051                }
6052                mForegroundProcesses.remove(token.pid);
6053                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6054                if (pr == null) {
6055                    return;
6056                }
6057                pr.forcingToForeground = null;
6058                updateProcessForegroundLocked(pr, false, false);
6059            }
6060            updateOomAdjLocked();
6061        }
6062    }
6063
6064    @Override
6065    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6066        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6067                "setProcessForeground()");
6068        synchronized(this) {
6069            boolean changed = false;
6070
6071            synchronized (mPidsSelfLocked) {
6072                ProcessRecord pr = mPidsSelfLocked.get(pid);
6073                if (pr == null && isForeground) {
6074                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6075                    return;
6076                }
6077                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6078                if (oldToken != null) {
6079                    oldToken.token.unlinkToDeath(oldToken, 0);
6080                    mForegroundProcesses.remove(pid);
6081                    if (pr != null) {
6082                        pr.forcingToForeground = null;
6083                    }
6084                    changed = true;
6085                }
6086                if (isForeground && token != null) {
6087                    ForegroundToken newToken = new ForegroundToken() {
6088                        @Override
6089                        public void binderDied() {
6090                            foregroundTokenDied(this);
6091                        }
6092                    };
6093                    newToken.pid = pid;
6094                    newToken.token = token;
6095                    try {
6096                        token.linkToDeath(newToken, 0);
6097                        mForegroundProcesses.put(pid, newToken);
6098                        pr.forcingToForeground = token;
6099                        changed = true;
6100                    } catch (RemoteException e) {
6101                        // If the process died while doing this, we will later
6102                        // do the cleanup with the process death link.
6103                    }
6104                }
6105            }
6106
6107            if (changed) {
6108                updateOomAdjLocked();
6109            }
6110        }
6111    }
6112
6113    // =========================================================
6114    // PERMISSIONS
6115    // =========================================================
6116
6117    static class PermissionController extends IPermissionController.Stub {
6118        ActivityManagerService mActivityManagerService;
6119        PermissionController(ActivityManagerService activityManagerService) {
6120            mActivityManagerService = activityManagerService;
6121        }
6122
6123        @Override
6124        public boolean checkPermission(String permission, int pid, int uid) {
6125            return mActivityManagerService.checkPermission(permission, pid,
6126                    uid) == PackageManager.PERMISSION_GRANTED;
6127        }
6128    }
6129
6130    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6131        @Override
6132        public int checkComponentPermission(String permission, int pid, int uid,
6133                int owningUid, boolean exported) {
6134            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6135                    owningUid, exported);
6136        }
6137
6138        @Override
6139        public Object getAMSLock() {
6140            return ActivityManagerService.this;
6141        }
6142    }
6143
6144    /**
6145     * This can be called with or without the global lock held.
6146     */
6147    int checkComponentPermission(String permission, int pid, int uid,
6148            int owningUid, boolean exported) {
6149        // We might be performing an operation on behalf of an indirect binder
6150        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6151        // client identity accordingly before proceeding.
6152        Identity tlsIdentity = sCallerIdentity.get();
6153        if (tlsIdentity != null) {
6154            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6155                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6156            uid = tlsIdentity.uid;
6157            pid = tlsIdentity.pid;
6158        }
6159
6160        if (pid == MY_PID) {
6161            return PackageManager.PERMISSION_GRANTED;
6162        }
6163
6164        return ActivityManager.checkComponentPermission(permission, uid,
6165                owningUid, exported);
6166    }
6167
6168    /**
6169     * As the only public entry point for permissions checking, this method
6170     * can enforce the semantic that requesting a check on a null global
6171     * permission is automatically denied.  (Internally a null permission
6172     * string is used when calling {@link #checkComponentPermission} in cases
6173     * when only uid-based security is needed.)
6174     *
6175     * This can be called with or without the global lock held.
6176     */
6177    @Override
6178    public int checkPermission(String permission, int pid, int uid) {
6179        if (permission == null) {
6180            return PackageManager.PERMISSION_DENIED;
6181        }
6182        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6183    }
6184
6185    /**
6186     * Binder IPC calls go through the public entry point.
6187     * This can be called with or without the global lock held.
6188     */
6189    int checkCallingPermission(String permission) {
6190        return checkPermission(permission,
6191                Binder.getCallingPid(),
6192                UserHandle.getAppId(Binder.getCallingUid()));
6193    }
6194
6195    /**
6196     * This can be called with or without the global lock held.
6197     */
6198    void enforceCallingPermission(String permission, String func) {
6199        if (checkCallingPermission(permission)
6200                == PackageManager.PERMISSION_GRANTED) {
6201            return;
6202        }
6203
6204        String msg = "Permission Denial: " + func + " from pid="
6205                + Binder.getCallingPid()
6206                + ", uid=" + Binder.getCallingUid()
6207                + " requires " + permission;
6208        Slog.w(TAG, msg);
6209        throw new SecurityException(msg);
6210    }
6211
6212    /**
6213     * Determine if UID is holding permissions required to access {@link Uri} in
6214     * the given {@link ProviderInfo}. Final permission checking is always done
6215     * in {@link ContentProvider}.
6216     */
6217    private final boolean checkHoldingPermissionsLocked(
6218            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6219        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6220                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6221        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6222            return false;
6223        }
6224        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6225    }
6226
6227    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6228            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6229        if (pi.applicationInfo.uid == uid) {
6230            return true;
6231        } else if (!pi.exported) {
6232            return false;
6233        }
6234
6235        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6236        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6237        try {
6238            // check if target holds top-level <provider> permissions
6239            if (!readMet && pi.readPermission != null && considerUidPermissions
6240                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6241                readMet = true;
6242            }
6243            if (!writeMet && pi.writePermission != null && considerUidPermissions
6244                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6245                writeMet = true;
6246            }
6247
6248            // track if unprotected read/write is allowed; any denied
6249            // <path-permission> below removes this ability
6250            boolean allowDefaultRead = pi.readPermission == null;
6251            boolean allowDefaultWrite = pi.writePermission == null;
6252
6253            // check if target holds any <path-permission> that match uri
6254            final PathPermission[] pps = pi.pathPermissions;
6255            if (pps != null) {
6256                final String path = grantUri.uri.getPath();
6257                int i = pps.length;
6258                while (i > 0 && (!readMet || !writeMet)) {
6259                    i--;
6260                    PathPermission pp = pps[i];
6261                    if (pp.match(path)) {
6262                        if (!readMet) {
6263                            final String pprperm = pp.getReadPermission();
6264                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6265                                    + pprperm + " for " + pp.getPath()
6266                                    + ": match=" + pp.match(path)
6267                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6268                            if (pprperm != null) {
6269                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6270                                        == PERMISSION_GRANTED) {
6271                                    readMet = true;
6272                                } else {
6273                                    allowDefaultRead = false;
6274                                }
6275                            }
6276                        }
6277                        if (!writeMet) {
6278                            final String ppwperm = pp.getWritePermission();
6279                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6280                                    + ppwperm + " for " + pp.getPath()
6281                                    + ": match=" + pp.match(path)
6282                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6283                            if (ppwperm != null) {
6284                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6285                                        == PERMISSION_GRANTED) {
6286                                    writeMet = true;
6287                                } else {
6288                                    allowDefaultWrite = false;
6289                                }
6290                            }
6291                        }
6292                    }
6293                }
6294            }
6295
6296            // grant unprotected <provider> read/write, if not blocked by
6297            // <path-permission> above
6298            if (allowDefaultRead) readMet = true;
6299            if (allowDefaultWrite) writeMet = true;
6300
6301        } catch (RemoteException e) {
6302            return false;
6303        }
6304
6305        return readMet && writeMet;
6306    }
6307
6308    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6309        ProviderInfo pi = null;
6310        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6311        if (cpr != null) {
6312            pi = cpr.info;
6313        } else {
6314            try {
6315                pi = AppGlobals.getPackageManager().resolveContentProvider(
6316                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6317            } catch (RemoteException ex) {
6318            }
6319        }
6320        return pi;
6321    }
6322
6323    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6324        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6325        if (targetUris != null) {
6326            return targetUris.get(grantUri);
6327        }
6328        return null;
6329    }
6330
6331    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6332            String targetPkg, int targetUid, GrantUri grantUri) {
6333        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6334        if (targetUris == null) {
6335            targetUris = Maps.newArrayMap();
6336            mGrantedUriPermissions.put(targetUid, targetUris);
6337        }
6338
6339        UriPermission perm = targetUris.get(grantUri);
6340        if (perm == null) {
6341            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6342            targetUris.put(grantUri, perm);
6343        }
6344
6345        return perm;
6346    }
6347
6348    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6349            final int modeFlags) {
6350        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6351        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6352                : UriPermission.STRENGTH_OWNED;
6353
6354        // Root gets to do everything.
6355        if (uid == 0) {
6356            return true;
6357        }
6358
6359        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6360        if (perms == null) return false;
6361
6362        // First look for exact match
6363        final UriPermission exactPerm = perms.get(grantUri);
6364        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6365            return true;
6366        }
6367
6368        // No exact match, look for prefixes
6369        final int N = perms.size();
6370        for (int i = 0; i < N; i++) {
6371            final UriPermission perm = perms.valueAt(i);
6372            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6373                    && perm.getStrength(modeFlags) >= minStrength) {
6374                return true;
6375            }
6376        }
6377
6378        return false;
6379    }
6380
6381    @Override
6382    public int checkUriPermission(Uri uri, int pid, int uid,
6383            final int modeFlags, int userId) {
6384        enforceNotIsolatedCaller("checkUriPermission");
6385
6386        // Another redirected-binder-call permissions check as in
6387        // {@link checkComponentPermission}.
6388        Identity tlsIdentity = sCallerIdentity.get();
6389        if (tlsIdentity != null) {
6390            uid = tlsIdentity.uid;
6391            pid = tlsIdentity.pid;
6392        }
6393
6394        // Our own process gets to do everything.
6395        if (pid == MY_PID) {
6396            return PackageManager.PERMISSION_GRANTED;
6397        }
6398        synchronized (this) {
6399            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6400                    ? PackageManager.PERMISSION_GRANTED
6401                    : PackageManager.PERMISSION_DENIED;
6402        }
6403    }
6404
6405    /**
6406     * Check if the targetPkg can be granted permission to access uri by
6407     * the callingUid using the given modeFlags.  Throws a security exception
6408     * if callingUid is not allowed to do this.  Returns the uid of the target
6409     * if the URI permission grant should be performed; returns -1 if it is not
6410     * needed (for example targetPkg already has permission to access the URI).
6411     * If you already know the uid of the target, you can supply it in
6412     * lastTargetUid else set that to -1.
6413     */
6414    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6415            final int modeFlags, int lastTargetUid) {
6416        if (!Intent.isAccessUriMode(modeFlags)) {
6417            return -1;
6418        }
6419
6420        if (targetPkg != null) {
6421            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6422                    "Checking grant " + targetPkg + " permission to " + grantUri);
6423        }
6424
6425        final IPackageManager pm = AppGlobals.getPackageManager();
6426
6427        // If this is not a content: uri, we can't do anything with it.
6428        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6429            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6430                    "Can't grant URI permission for non-content URI: " + grantUri);
6431            return -1;
6432        }
6433
6434        final String authority = grantUri.uri.getAuthority();
6435        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6436        if (pi == null) {
6437            Slog.w(TAG, "No content provider found for permission check: " +
6438                    grantUri.uri.toSafeString());
6439            return -1;
6440        }
6441
6442        int targetUid = lastTargetUid;
6443        if (targetUid < 0 && targetPkg != null) {
6444            try {
6445                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6446                if (targetUid < 0) {
6447                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6448                            "Can't grant URI permission no uid for: " + targetPkg);
6449                    return -1;
6450                }
6451            } catch (RemoteException ex) {
6452                return -1;
6453            }
6454        }
6455
6456        if (targetUid >= 0) {
6457            // First...  does the target actually need this permission?
6458            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6459                // No need to grant the target this permission.
6460                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6461                        "Target " + targetPkg + " already has full permission to " + grantUri);
6462                return -1;
6463            }
6464        } else {
6465            // First...  there is no target package, so can anyone access it?
6466            boolean allowed = pi.exported;
6467            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6468                if (pi.readPermission != null) {
6469                    allowed = false;
6470                }
6471            }
6472            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6473                if (pi.writePermission != null) {
6474                    allowed = false;
6475                }
6476            }
6477            if (allowed) {
6478                return -1;
6479            }
6480        }
6481
6482        /* There is a special cross user grant if:
6483         * - The target is on another user.
6484         * - Apps on the current user can access the uri without any uid permissions.
6485         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6486         * grant uri permissions.
6487         */
6488        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6489                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6490                modeFlags, false /*without considering the uid permissions*/);
6491
6492        // Second...  is the provider allowing granting of URI permissions?
6493        if (!specialCrossUserGrant) {
6494            if (!pi.grantUriPermissions) {
6495                throw new SecurityException("Provider " + pi.packageName
6496                        + "/" + pi.name
6497                        + " does not allow granting of Uri permissions (uri "
6498                        + grantUri + ")");
6499            }
6500            if (pi.uriPermissionPatterns != null) {
6501                final int N = pi.uriPermissionPatterns.length;
6502                boolean allowed = false;
6503                for (int i=0; i<N; i++) {
6504                    if (pi.uriPermissionPatterns[i] != null
6505                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6506                        allowed = true;
6507                        break;
6508                    }
6509                }
6510                if (!allowed) {
6511                    throw new SecurityException("Provider " + pi.packageName
6512                            + "/" + pi.name
6513                            + " does not allow granting of permission to path of Uri "
6514                            + grantUri);
6515                }
6516            }
6517        }
6518
6519        // Third...  does the caller itself have permission to access
6520        // this uri?
6521        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6522            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6523                // Require they hold a strong enough Uri permission
6524                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6525                    throw new SecurityException("Uid " + callingUid
6526                            + " does not have permission to uri " + grantUri);
6527                }
6528            }
6529        }
6530        return targetUid;
6531    }
6532
6533    @Override
6534    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6535            final int modeFlags, int userId) {
6536        enforceNotIsolatedCaller("checkGrantUriPermission");
6537        synchronized(this) {
6538            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6539                    new GrantUri(userId, uri, false), modeFlags, -1);
6540        }
6541    }
6542
6543    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6544            final int modeFlags, UriPermissionOwner owner) {
6545        if (!Intent.isAccessUriMode(modeFlags)) {
6546            return;
6547        }
6548
6549        // So here we are: the caller has the assumed permission
6550        // to the uri, and the target doesn't.  Let's now give this to
6551        // the target.
6552
6553        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6554                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6555
6556        final String authority = grantUri.uri.getAuthority();
6557        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6558        if (pi == null) {
6559            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6560            return;
6561        }
6562
6563        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6564            grantUri.prefix = true;
6565        }
6566        final UriPermission perm = findOrCreateUriPermissionLocked(
6567                pi.packageName, targetPkg, targetUid, grantUri);
6568        perm.grantModes(modeFlags, owner);
6569    }
6570
6571    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6572            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6573        if (targetPkg == null) {
6574            throw new NullPointerException("targetPkg");
6575        }
6576        int targetUid;
6577        final IPackageManager pm = AppGlobals.getPackageManager();
6578        try {
6579            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6580        } catch (RemoteException ex) {
6581            return;
6582        }
6583
6584        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6585                targetUid);
6586        if (targetUid < 0) {
6587            return;
6588        }
6589
6590        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6591                owner);
6592    }
6593
6594    static class NeededUriGrants extends ArrayList<GrantUri> {
6595        final String targetPkg;
6596        final int targetUid;
6597        final int flags;
6598
6599        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6600            this.targetPkg = targetPkg;
6601            this.targetUid = targetUid;
6602            this.flags = flags;
6603        }
6604    }
6605
6606    /**
6607     * Like checkGrantUriPermissionLocked, but takes an Intent.
6608     */
6609    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6610            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6611        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6612                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6613                + " clip=" + (intent != null ? intent.getClipData() : null)
6614                + " from " + intent + "; flags=0x"
6615                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6616
6617        if (targetPkg == null) {
6618            throw new NullPointerException("targetPkg");
6619        }
6620
6621        if (intent == null) {
6622            return null;
6623        }
6624        Uri data = intent.getData();
6625        ClipData clip = intent.getClipData();
6626        if (data == null && clip == null) {
6627            return null;
6628        }
6629        final IPackageManager pm = AppGlobals.getPackageManager();
6630        int targetUid;
6631        if (needed != null) {
6632            targetUid = needed.targetUid;
6633        } else {
6634            try {
6635                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6636            } catch (RemoteException ex) {
6637                return null;
6638            }
6639            if (targetUid < 0) {
6640                if (DEBUG_URI_PERMISSION) {
6641                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6642                            + " on user " + targetUserId);
6643                }
6644                return null;
6645            }
6646        }
6647        if (data != null) {
6648            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6649            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6650                    targetUid);
6651            if (targetUid > 0) {
6652                if (needed == null) {
6653                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6654                }
6655                needed.add(grantUri);
6656            }
6657        }
6658        if (clip != null) {
6659            for (int i=0; i<clip.getItemCount(); i++) {
6660                Uri uri = clip.getItemAt(i).getUri();
6661                if (uri != null) {
6662                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6663                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6664                            targetUid);
6665                    if (targetUid > 0) {
6666                        if (needed == null) {
6667                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6668                        }
6669                        needed.add(grantUri);
6670                    }
6671                } else {
6672                    Intent clipIntent = clip.getItemAt(i).getIntent();
6673                    if (clipIntent != null) {
6674                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6675                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6676                        if (newNeeded != null) {
6677                            needed = newNeeded;
6678                        }
6679                    }
6680                }
6681            }
6682        }
6683
6684        return needed;
6685    }
6686
6687    /**
6688     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6689     */
6690    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6691            UriPermissionOwner owner) {
6692        if (needed != null) {
6693            for (int i=0; i<needed.size(); i++) {
6694                GrantUri grantUri = needed.get(i);
6695                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6696                        grantUri, needed.flags, owner);
6697            }
6698        }
6699    }
6700
6701    void grantUriPermissionFromIntentLocked(int callingUid,
6702            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6703        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6704                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6705        if (needed == null) {
6706            return;
6707        }
6708
6709        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6710    }
6711
6712    @Override
6713    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6714            final int modeFlags, int userId) {
6715        enforceNotIsolatedCaller("grantUriPermission");
6716        GrantUri grantUri = new GrantUri(userId, uri, false);
6717        synchronized(this) {
6718            final ProcessRecord r = getRecordForAppLocked(caller);
6719            if (r == null) {
6720                throw new SecurityException("Unable to find app for caller "
6721                        + caller
6722                        + " when granting permission to uri " + grantUri);
6723            }
6724            if (targetPkg == null) {
6725                throw new IllegalArgumentException("null target");
6726            }
6727            if (grantUri == null) {
6728                throw new IllegalArgumentException("null uri");
6729            }
6730
6731            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6732                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6733                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6734                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6735
6736            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6737                    UserHandle.getUserId(r.uid));
6738        }
6739    }
6740
6741    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6742        if (perm.modeFlags == 0) {
6743            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6744                    perm.targetUid);
6745            if (perms != null) {
6746                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6747                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6748
6749                perms.remove(perm.uri);
6750                if (perms.isEmpty()) {
6751                    mGrantedUriPermissions.remove(perm.targetUid);
6752                }
6753            }
6754        }
6755    }
6756
6757    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6758        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6759
6760        final IPackageManager pm = AppGlobals.getPackageManager();
6761        final String authority = grantUri.uri.getAuthority();
6762        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6763        if (pi == null) {
6764            Slog.w(TAG, "No content provider found for permission revoke: "
6765                    + grantUri.toSafeString());
6766            return;
6767        }
6768
6769        // Does the caller have this permission on the URI?
6770        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6771            // Right now, if you are not the original owner of the permission,
6772            // you are not allowed to revoke it.
6773            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6774                throw new SecurityException("Uid " + callingUid
6775                        + " does not have permission to uri " + grantUri);
6776            //}
6777        }
6778
6779        boolean persistChanged = false;
6780
6781        // Go through all of the permissions and remove any that match.
6782        int N = mGrantedUriPermissions.size();
6783        for (int i = 0; i < N; i++) {
6784            final int targetUid = mGrantedUriPermissions.keyAt(i);
6785            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6786
6787            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6788                final UriPermission perm = it.next();
6789                if (perm.uri.sourceUserId == grantUri.sourceUserId
6790                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6791                    if (DEBUG_URI_PERMISSION)
6792                        Slog.v(TAG,
6793                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6794                    persistChanged |= perm.revokeModes(
6795                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6796                    if (perm.modeFlags == 0) {
6797                        it.remove();
6798                    }
6799                }
6800            }
6801
6802            if (perms.isEmpty()) {
6803                mGrantedUriPermissions.remove(targetUid);
6804                N--;
6805                i--;
6806            }
6807        }
6808
6809        if (persistChanged) {
6810            schedulePersistUriGrants();
6811        }
6812    }
6813
6814    @Override
6815    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6816            int userId) {
6817        enforceNotIsolatedCaller("revokeUriPermission");
6818        synchronized(this) {
6819            final ProcessRecord r = getRecordForAppLocked(caller);
6820            if (r == null) {
6821                throw new SecurityException("Unable to find app for caller "
6822                        + caller
6823                        + " when revoking permission to uri " + uri);
6824            }
6825            if (uri == null) {
6826                Slog.w(TAG, "revokeUriPermission: null uri");
6827                return;
6828            }
6829
6830            if (!Intent.isAccessUriMode(modeFlags)) {
6831                return;
6832            }
6833
6834            final IPackageManager pm = AppGlobals.getPackageManager();
6835            final String authority = uri.getAuthority();
6836            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6837            if (pi == null) {
6838                Slog.w(TAG, "No content provider found for permission revoke: "
6839                        + uri.toSafeString());
6840                return;
6841            }
6842
6843            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6844        }
6845    }
6846
6847    /**
6848     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6849     * given package.
6850     *
6851     * @param packageName Package name to match, or {@code null} to apply to all
6852     *            packages.
6853     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6854     *            to all users.
6855     * @param persistable If persistable grants should be removed.
6856     */
6857    private void removeUriPermissionsForPackageLocked(
6858            String packageName, int userHandle, boolean persistable) {
6859        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6860            throw new IllegalArgumentException("Must narrow by either package or user");
6861        }
6862
6863        boolean persistChanged = false;
6864
6865        int N = mGrantedUriPermissions.size();
6866        for (int i = 0; i < N; i++) {
6867            final int targetUid = mGrantedUriPermissions.keyAt(i);
6868            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6869
6870            // Only inspect grants matching user
6871            if (userHandle == UserHandle.USER_ALL
6872                    || userHandle == UserHandle.getUserId(targetUid)) {
6873                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6874                    final UriPermission perm = it.next();
6875
6876                    // Only inspect grants matching package
6877                    if (packageName == null || perm.sourcePkg.equals(packageName)
6878                            || perm.targetPkg.equals(packageName)) {
6879                        persistChanged |= perm.revokeModes(
6880                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6881
6882                        // Only remove when no modes remain; any persisted grants
6883                        // will keep this alive.
6884                        if (perm.modeFlags == 0) {
6885                            it.remove();
6886                        }
6887                    }
6888                }
6889
6890                if (perms.isEmpty()) {
6891                    mGrantedUriPermissions.remove(targetUid);
6892                    N--;
6893                    i--;
6894                }
6895            }
6896        }
6897
6898        if (persistChanged) {
6899            schedulePersistUriGrants();
6900        }
6901    }
6902
6903    @Override
6904    public IBinder newUriPermissionOwner(String name) {
6905        enforceNotIsolatedCaller("newUriPermissionOwner");
6906        synchronized(this) {
6907            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6908            return owner.getExternalTokenLocked();
6909        }
6910    }
6911
6912    @Override
6913    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6914            final int modeFlags, int sourceUserId, int targetUserId) {
6915        synchronized(this) {
6916            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6917            if (owner == null) {
6918                throw new IllegalArgumentException("Unknown owner: " + token);
6919            }
6920            if (fromUid != Binder.getCallingUid()) {
6921                if (Binder.getCallingUid() != Process.myUid()) {
6922                    // Only system code can grant URI permissions on behalf
6923                    // of other users.
6924                    throw new SecurityException("nice try");
6925                }
6926            }
6927            if (targetPkg == null) {
6928                throw new IllegalArgumentException("null target");
6929            }
6930            if (uri == null) {
6931                throw new IllegalArgumentException("null uri");
6932            }
6933
6934            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6935                    modeFlags, owner, targetUserId);
6936        }
6937    }
6938
6939    @Override
6940    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6941        synchronized(this) {
6942            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6943            if (owner == null) {
6944                throw new IllegalArgumentException("Unknown owner: " + token);
6945            }
6946
6947            if (uri == null) {
6948                owner.removeUriPermissionsLocked(mode);
6949            } else {
6950                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6951            }
6952        }
6953    }
6954
6955    private void schedulePersistUriGrants() {
6956        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6957            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6958                    10 * DateUtils.SECOND_IN_MILLIS);
6959        }
6960    }
6961
6962    private void writeGrantedUriPermissions() {
6963        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6964
6965        // Snapshot permissions so we can persist without lock
6966        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6967        synchronized (this) {
6968            final int size = mGrantedUriPermissions.size();
6969            for (int i = 0; i < size; i++) {
6970                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6971                for (UriPermission perm : perms.values()) {
6972                    if (perm.persistedModeFlags != 0) {
6973                        persist.add(perm.snapshot());
6974                    }
6975                }
6976            }
6977        }
6978
6979        FileOutputStream fos = null;
6980        try {
6981            fos = mGrantFile.startWrite();
6982
6983            XmlSerializer out = new FastXmlSerializer();
6984            out.setOutput(fos, "utf-8");
6985            out.startDocument(null, true);
6986            out.startTag(null, TAG_URI_GRANTS);
6987            for (UriPermission.Snapshot perm : persist) {
6988                out.startTag(null, TAG_URI_GRANT);
6989                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6990                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6991                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6992                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6993                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6994                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6995                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6996                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6997                out.endTag(null, TAG_URI_GRANT);
6998            }
6999            out.endTag(null, TAG_URI_GRANTS);
7000            out.endDocument();
7001
7002            mGrantFile.finishWrite(fos);
7003        } catch (IOException e) {
7004            if (fos != null) {
7005                mGrantFile.failWrite(fos);
7006            }
7007        }
7008    }
7009
7010    private void readGrantedUriPermissionsLocked() {
7011        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7012
7013        final long now = System.currentTimeMillis();
7014
7015        FileInputStream fis = null;
7016        try {
7017            fis = mGrantFile.openRead();
7018            final XmlPullParser in = Xml.newPullParser();
7019            in.setInput(fis, null);
7020
7021            int type;
7022            while ((type = in.next()) != END_DOCUMENT) {
7023                final String tag = in.getName();
7024                if (type == START_TAG) {
7025                    if (TAG_URI_GRANT.equals(tag)) {
7026                        final int sourceUserId;
7027                        final int targetUserId;
7028                        final int userHandle = readIntAttribute(in,
7029                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7030                        if (userHandle != UserHandle.USER_NULL) {
7031                            // For backwards compatibility.
7032                            sourceUserId = userHandle;
7033                            targetUserId = userHandle;
7034                        } else {
7035                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7036                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7037                        }
7038                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7039                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7040                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7041                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7042                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7043                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7044
7045                        // Sanity check that provider still belongs to source package
7046                        final ProviderInfo pi = getProviderInfoLocked(
7047                                uri.getAuthority(), sourceUserId);
7048                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7049                            int targetUid = -1;
7050                            try {
7051                                targetUid = AppGlobals.getPackageManager()
7052                                        .getPackageUid(targetPkg, targetUserId);
7053                            } catch (RemoteException e) {
7054                            }
7055                            if (targetUid != -1) {
7056                                final UriPermission perm = findOrCreateUriPermissionLocked(
7057                                        sourcePkg, targetPkg, targetUid,
7058                                        new GrantUri(sourceUserId, uri, prefix));
7059                                perm.initPersistedModes(modeFlags, createdTime);
7060                            }
7061                        } else {
7062                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7063                                    + " but instead found " + pi);
7064                        }
7065                    }
7066                }
7067            }
7068        } catch (FileNotFoundException e) {
7069            // Missing grants is okay
7070        } catch (IOException e) {
7071            Log.wtf(TAG, "Failed reading Uri grants", e);
7072        } catch (XmlPullParserException e) {
7073            Log.wtf(TAG, "Failed reading Uri grants", e);
7074        } finally {
7075            IoUtils.closeQuietly(fis);
7076        }
7077    }
7078
7079    @Override
7080    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7081        enforceNotIsolatedCaller("takePersistableUriPermission");
7082
7083        Preconditions.checkFlagsArgument(modeFlags,
7084                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7085
7086        synchronized (this) {
7087            final int callingUid = Binder.getCallingUid();
7088            boolean persistChanged = false;
7089            GrantUri grantUri = new GrantUri(userId, uri, false);
7090
7091            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7092                    new GrantUri(userId, uri, false));
7093            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7094                    new GrantUri(userId, uri, true));
7095
7096            final boolean exactValid = (exactPerm != null)
7097                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7098            final boolean prefixValid = (prefixPerm != null)
7099                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7100
7101            if (!(exactValid || prefixValid)) {
7102                throw new SecurityException("No persistable permission grants found for UID "
7103                        + callingUid + " and Uri " + grantUri.toSafeString());
7104            }
7105
7106            if (exactValid) {
7107                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7108            }
7109            if (prefixValid) {
7110                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7111            }
7112
7113            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7114
7115            if (persistChanged) {
7116                schedulePersistUriGrants();
7117            }
7118        }
7119    }
7120
7121    @Override
7122    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7123        enforceNotIsolatedCaller("releasePersistableUriPermission");
7124
7125        Preconditions.checkFlagsArgument(modeFlags,
7126                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7127
7128        synchronized (this) {
7129            final int callingUid = Binder.getCallingUid();
7130            boolean persistChanged = false;
7131
7132            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7133                    new GrantUri(userId, uri, false));
7134            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7135                    new GrantUri(userId, uri, true));
7136            if (exactPerm == null && prefixPerm == null) {
7137                throw new SecurityException("No permission grants found for UID " + callingUid
7138                        + " and Uri " + uri.toSafeString());
7139            }
7140
7141            if (exactPerm != null) {
7142                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7143                removeUriPermissionIfNeededLocked(exactPerm);
7144            }
7145            if (prefixPerm != null) {
7146                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7147                removeUriPermissionIfNeededLocked(prefixPerm);
7148            }
7149
7150            if (persistChanged) {
7151                schedulePersistUriGrants();
7152            }
7153        }
7154    }
7155
7156    /**
7157     * Prune any older {@link UriPermission} for the given UID until outstanding
7158     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7159     *
7160     * @return if any mutations occured that require persisting.
7161     */
7162    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7163        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7164        if (perms == null) return false;
7165        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7166
7167        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7168        for (UriPermission perm : perms.values()) {
7169            if (perm.persistedModeFlags != 0) {
7170                persisted.add(perm);
7171            }
7172        }
7173
7174        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7175        if (trimCount <= 0) return false;
7176
7177        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7178        for (int i = 0; i < trimCount; i++) {
7179            final UriPermission perm = persisted.get(i);
7180
7181            if (DEBUG_URI_PERMISSION) {
7182                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7183            }
7184
7185            perm.releasePersistableModes(~0);
7186            removeUriPermissionIfNeededLocked(perm);
7187        }
7188
7189        return true;
7190    }
7191
7192    @Override
7193    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7194            String packageName, boolean incoming) {
7195        enforceNotIsolatedCaller("getPersistedUriPermissions");
7196        Preconditions.checkNotNull(packageName, "packageName");
7197
7198        final int callingUid = Binder.getCallingUid();
7199        final IPackageManager pm = AppGlobals.getPackageManager();
7200        try {
7201            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7202            if (packageUid != callingUid) {
7203                throw new SecurityException(
7204                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7205            }
7206        } catch (RemoteException e) {
7207            throw new SecurityException("Failed to verify package name ownership");
7208        }
7209
7210        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7211        synchronized (this) {
7212            if (incoming) {
7213                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7214                        callingUid);
7215                if (perms == null) {
7216                    Slog.w(TAG, "No permission grants found for " + packageName);
7217                } else {
7218                    for (UriPermission perm : perms.values()) {
7219                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7220                            result.add(perm.buildPersistedPublicApiObject());
7221                        }
7222                    }
7223                }
7224            } else {
7225                final int size = mGrantedUriPermissions.size();
7226                for (int i = 0; i < size; i++) {
7227                    final ArrayMap<GrantUri, UriPermission> perms =
7228                            mGrantedUriPermissions.valueAt(i);
7229                    for (UriPermission perm : perms.values()) {
7230                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7231                            result.add(perm.buildPersistedPublicApiObject());
7232                        }
7233                    }
7234                }
7235            }
7236        }
7237        return new ParceledListSlice<android.content.UriPermission>(result);
7238    }
7239
7240    @Override
7241    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7242        synchronized (this) {
7243            ProcessRecord app =
7244                who != null ? getRecordForAppLocked(who) : null;
7245            if (app == null) return;
7246
7247            Message msg = Message.obtain();
7248            msg.what = WAIT_FOR_DEBUGGER_MSG;
7249            msg.obj = app;
7250            msg.arg1 = waiting ? 1 : 0;
7251            mHandler.sendMessage(msg);
7252        }
7253    }
7254
7255    @Override
7256    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7257        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7258        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7259        outInfo.availMem = Process.getFreeMemory();
7260        outInfo.totalMem = Process.getTotalMemory();
7261        outInfo.threshold = homeAppMem;
7262        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7263        outInfo.hiddenAppThreshold = cachedAppMem;
7264        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7265                ProcessList.SERVICE_ADJ);
7266        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7267                ProcessList.VISIBLE_APP_ADJ);
7268        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7269                ProcessList.FOREGROUND_APP_ADJ);
7270    }
7271
7272    // =========================================================
7273    // TASK MANAGEMENT
7274    // =========================================================
7275
7276    @Override
7277    public List<IAppTask> getAppTasks() {
7278        final PackageManager pm = mContext.getPackageManager();
7279        int callingUid = Binder.getCallingUid();
7280        long ident = Binder.clearCallingIdentity();
7281
7282        // Compose the list of packages for this id to test against
7283        HashSet<String> packages = new HashSet<String>();
7284        String[] uidPackages = pm.getPackagesForUid(callingUid);
7285        for (int i = 0; i < uidPackages.length; i++) {
7286            packages.add(uidPackages[i]);
7287        }
7288
7289        synchronized(this) {
7290            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7291            try {
7292                if (localLOGV) Slog.v(TAG, "getAppTasks");
7293
7294                final int N = mRecentTasks.size();
7295                for (int i = 0; i < N; i++) {
7296                    TaskRecord tr = mRecentTasks.get(i);
7297                    // Skip tasks that are not created by the caller
7298                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7299                        ActivityManager.RecentTaskInfo taskInfo =
7300                                createRecentTaskInfoFromTaskRecord(tr);
7301                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7302                        list.add(taskImpl);
7303                    }
7304                }
7305            } finally {
7306                Binder.restoreCallingIdentity(ident);
7307            }
7308            return list;
7309        }
7310    }
7311
7312    @Override
7313    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7314        final int callingUid = Binder.getCallingUid();
7315        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7316
7317        synchronized(this) {
7318            if (localLOGV) Slog.v(
7319                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7320
7321            final boolean allowed = checkCallingPermission(
7322                    android.Manifest.permission.GET_TASKS)
7323                    == PackageManager.PERMISSION_GRANTED;
7324            if (!allowed) {
7325                Slog.w(TAG, "getTasks: caller " + callingUid
7326                        + " does not hold GET_TASKS; limiting output");
7327            }
7328
7329            // TODO: Improve with MRU list from all ActivityStacks.
7330            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7331        }
7332
7333        return list;
7334    }
7335
7336    TaskRecord getMostRecentTask() {
7337        return mRecentTasks.get(0);
7338    }
7339
7340    /**
7341     * Creates a new RecentTaskInfo from a TaskRecord.
7342     */
7343    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7344        // Update the task description to reflect any changes in the task stack
7345        tr.updateTaskDescription();
7346
7347        // Compose the recent task info
7348        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7349        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7350        rti.persistentId = tr.taskId;
7351        rti.baseIntent = new Intent(tr.getBaseIntent());
7352        rti.origActivity = tr.origActivity;
7353        rti.description = tr.lastDescription;
7354        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7355        rti.userId = tr.userId;
7356        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7357        rti.firstActiveTime = tr.firstActiveTime;
7358        rti.lastActiveTime = tr.lastActiveTime;
7359        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7360        return rti;
7361    }
7362
7363    @Override
7364    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7365        final int callingUid = Binder.getCallingUid();
7366        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7367                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7368
7369        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7370        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7371        synchronized (this) {
7372            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7373                    == PackageManager.PERMISSION_GRANTED;
7374            if (!allowed) {
7375                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7376                        + " does not hold GET_TASKS; limiting output");
7377            }
7378            final boolean detailed = checkCallingPermission(
7379                    android.Manifest.permission.GET_DETAILED_TASKS)
7380                    == PackageManager.PERMISSION_GRANTED;
7381
7382            IPackageManager pm = AppGlobals.getPackageManager();
7383
7384            final int N = mRecentTasks.size();
7385            ArrayList<ActivityManager.RecentTaskInfo> res
7386                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7387                            maxNum < N ? maxNum : N);
7388
7389            final Set<Integer> includedUsers;
7390            if (includeProfiles) {
7391                includedUsers = getProfileIdsLocked(userId);
7392            } else {
7393                includedUsers = new HashSet<Integer>();
7394            }
7395            includedUsers.add(Integer.valueOf(userId));
7396
7397            // Regroup affiliated tasks together.
7398            for (int i = 0; i < N; ) {
7399                TaskRecord task = mRecentTasks.remove(i);
7400                if (mTmpRecents.contains(task)) {
7401                    continue;
7402                }
7403                int affiliatedTaskId = task.mAffiliatedTaskId;
7404                while (true) {
7405                    TaskRecord next = task.mNextAffiliate;
7406                    if (next == null) {
7407                        break;
7408                    }
7409                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7410                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7411                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7412                        task.setNextAffiliate(null);
7413                        if (next.mPrevAffiliate == task) {
7414                            next.setPrevAffiliate(null);
7415                        }
7416                        break;
7417                    }
7418                    if (next.mPrevAffiliate != task) {
7419                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7420                                next.mPrevAffiliate + " task=" + task);
7421                        next.setPrevAffiliate(null);
7422                        break;
7423                    }
7424                    if (!mRecentTasks.contains(next)) {
7425                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7426                        task.setNextAffiliate(null);
7427                        if (next.mPrevAffiliate == task) {
7428                            next.setPrevAffiliate(null);
7429                        }
7430                        break;
7431                    }
7432                    task = next;
7433                }
7434                // task is now the end of the list
7435                do {
7436                    mRecentTasks.remove(task);
7437                    mRecentTasks.add(i++, task);
7438                    mTmpRecents.add(task);
7439                } while ((task = task.mPrevAffiliate) != null);
7440            }
7441            mTmpRecents.clear();
7442            // mRecentTasks is now in sorted, affiliated order.
7443
7444            for (int i=0; i<N && maxNum > 0; i++) {
7445                TaskRecord tr = mRecentTasks.get(i);
7446                // Only add calling user or related users recent tasks
7447                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7448
7449                // Return the entry if desired by the caller.  We always return
7450                // the first entry, because callers always expect this to be the
7451                // foreground app.  We may filter others if the caller has
7452                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7453                // we should exclude the entry.
7454
7455                if (i == 0
7456                        || withExcluded
7457                        || (tr.intent == null)
7458                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7459                                == 0)) {
7460                    if (!allowed) {
7461                        // If the caller doesn't have the GET_TASKS permission, then only
7462                        // allow them to see a small subset of tasks -- their own and home.
7463                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7464                            continue;
7465                        }
7466                    }
7467                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7468                        // Don't include auto remove tasks that are finished or finishing.
7469                        continue;
7470                    }
7471
7472                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7473                    if (!detailed) {
7474                        rti.baseIntent.replaceExtras((Bundle)null);
7475                    }
7476
7477                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7478                        // Check whether this activity is currently available.
7479                        try {
7480                            if (rti.origActivity != null) {
7481                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7482                                        == null) {
7483                                    continue;
7484                                }
7485                            } else if (rti.baseIntent != null) {
7486                                if (pm.queryIntentActivities(rti.baseIntent,
7487                                        null, 0, userId) == null) {
7488                                    continue;
7489                                }
7490                            }
7491                        } catch (RemoteException e) {
7492                            // Will never happen.
7493                        }
7494                    }
7495
7496                    res.add(rti);
7497                    maxNum--;
7498                }
7499            }
7500            return res;
7501        }
7502    }
7503
7504    private TaskRecord recentTaskForIdLocked(int id) {
7505        final int N = mRecentTasks.size();
7506            for (int i=0; i<N; i++) {
7507                TaskRecord tr = mRecentTasks.get(i);
7508                if (tr.taskId == id) {
7509                    return tr;
7510                }
7511            }
7512            return null;
7513    }
7514
7515    @Override
7516    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7517        synchronized (this) {
7518            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7519                    "getTaskThumbnail()");
7520            TaskRecord tr = recentTaskForIdLocked(id);
7521            if (tr != null) {
7522                return tr.getTaskThumbnailLocked();
7523            }
7524        }
7525        return null;
7526    }
7527
7528    @Override
7529    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7530        synchronized (this) {
7531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7532            if (r != null) {
7533                r.taskDescription = td;
7534                r.task.updateTaskDescription();
7535            }
7536        }
7537    }
7538
7539    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7540        if (!pr.killedByAm) {
7541            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7542            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7543                    pr.processName, pr.setAdj, reason);
7544            pr.killedByAm = true;
7545            Process.killProcessQuiet(pr.pid);
7546            Process.killProcessGroup(pr.info.uid, pr.pid);
7547        }
7548    }
7549
7550    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7551        tr.disposeThumbnail();
7552        mRecentTasks.remove(tr);
7553        tr.closeRecentsChain();
7554        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7555        Intent baseIntent = new Intent(
7556                tr.intent != null ? tr.intent : tr.affinityIntent);
7557        ComponentName component = baseIntent.getComponent();
7558        if (component == null) {
7559            Slog.w(TAG, "Now component for base intent of task: " + tr);
7560            return;
7561        }
7562
7563        // Find any running services associated with this app.
7564        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7565
7566        if (killProcesses) {
7567            // Find any running processes associated with this app.
7568            final String pkg = component.getPackageName();
7569            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7570            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7571            for (int i=0; i<pmap.size(); i++) {
7572                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7573                for (int j=0; j<uids.size(); j++) {
7574                    ProcessRecord proc = uids.valueAt(j);
7575                    if (proc.userId != tr.userId) {
7576                        continue;
7577                    }
7578                    if (!proc.pkgList.containsKey(pkg)) {
7579                        continue;
7580                    }
7581                    procs.add(proc);
7582                }
7583            }
7584
7585            // Kill the running processes.
7586            for (int i=0; i<procs.size(); i++) {
7587                ProcessRecord pr = procs.get(i);
7588                if (pr == mHomeProcess) {
7589                    // Don't kill the home process along with tasks from the same package.
7590                    continue;
7591                }
7592                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7593                    killUnneededProcessLocked(pr, "remove task");
7594                } else {
7595                    pr.waitingToKill = "remove task";
7596                }
7597            }
7598        }
7599    }
7600
7601    /**
7602     * Removes the task with the specified task id.
7603     *
7604     * @param taskId Identifier of the task to be removed.
7605     * @param flags Additional operational flags.  May be 0 or
7606     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7607     * @return Returns true if the given task was found and removed.
7608     */
7609    private boolean removeTaskByIdLocked(int taskId, int flags) {
7610        TaskRecord tr = recentTaskForIdLocked(taskId);
7611        if (tr != null) {
7612            tr.removeTaskActivitiesLocked();
7613            cleanUpRemovedTaskLocked(tr, flags);
7614            if (tr.isPersistable) {
7615                notifyTaskPersisterLocked(tr, true);
7616            }
7617            return true;
7618        }
7619        return false;
7620    }
7621
7622    @Override
7623    public boolean removeTask(int taskId, int flags) {
7624        synchronized (this) {
7625            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7626                    "removeTask()");
7627            long ident = Binder.clearCallingIdentity();
7628            try {
7629                return removeTaskByIdLocked(taskId, flags);
7630            } finally {
7631                Binder.restoreCallingIdentity(ident);
7632            }
7633        }
7634    }
7635
7636    /**
7637     * TODO: Add mController hook
7638     */
7639    @Override
7640    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7641        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7642                "moveTaskToFront()");
7643
7644        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7645        synchronized(this) {
7646            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7647                    Binder.getCallingUid(), "Task to front")) {
7648                ActivityOptions.abort(options);
7649                return;
7650            }
7651            final long origId = Binder.clearCallingIdentity();
7652            try {
7653                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7654                if (task == null) {
7655                    return;
7656                }
7657                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7658                    mStackSupervisor.showLockTaskToast();
7659                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7660                    return;
7661                }
7662                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7663                if (prev != null && prev.isRecentsActivity()) {
7664                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7665                }
7666                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7667            } finally {
7668                Binder.restoreCallingIdentity(origId);
7669            }
7670            ActivityOptions.abort(options);
7671        }
7672    }
7673
7674    @Override
7675    public void moveTaskToBack(int taskId) {
7676        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7677                "moveTaskToBack()");
7678
7679        synchronized(this) {
7680            TaskRecord tr = recentTaskForIdLocked(taskId);
7681            if (tr != null) {
7682                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7683                ActivityStack stack = tr.stack;
7684                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7685                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7686                            Binder.getCallingUid(), "Task to back")) {
7687                        return;
7688                    }
7689                }
7690                final long origId = Binder.clearCallingIdentity();
7691                try {
7692                    stack.moveTaskToBackLocked(taskId, null);
7693                } finally {
7694                    Binder.restoreCallingIdentity(origId);
7695                }
7696            }
7697        }
7698    }
7699
7700    /**
7701     * Moves an activity, and all of the other activities within the same task, to the bottom
7702     * of the history stack.  The activity's order within the task is unchanged.
7703     *
7704     * @param token A reference to the activity we wish to move
7705     * @param nonRoot If false then this only works if the activity is the root
7706     *                of a task; if true it will work for any activity in a task.
7707     * @return Returns true if the move completed, false if not.
7708     */
7709    @Override
7710    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7711        enforceNotIsolatedCaller("moveActivityTaskToBack");
7712        synchronized(this) {
7713            final long origId = Binder.clearCallingIdentity();
7714            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7715            if (taskId >= 0) {
7716                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7717            }
7718            Binder.restoreCallingIdentity(origId);
7719        }
7720        return false;
7721    }
7722
7723    @Override
7724    public void moveTaskBackwards(int task) {
7725        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7726                "moveTaskBackwards()");
7727
7728        synchronized(this) {
7729            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7730                    Binder.getCallingUid(), "Task backwards")) {
7731                return;
7732            }
7733            final long origId = Binder.clearCallingIdentity();
7734            moveTaskBackwardsLocked(task);
7735            Binder.restoreCallingIdentity(origId);
7736        }
7737    }
7738
7739    private final void moveTaskBackwardsLocked(int task) {
7740        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7741    }
7742
7743    @Override
7744    public IBinder getHomeActivityToken() throws RemoteException {
7745        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7746                "getHomeActivityToken()");
7747        synchronized (this) {
7748            return mStackSupervisor.getHomeActivityToken();
7749        }
7750    }
7751
7752    @Override
7753    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7754            IActivityContainerCallback callback) throws RemoteException {
7755        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7756                "createActivityContainer()");
7757        synchronized (this) {
7758            if (parentActivityToken == null) {
7759                throw new IllegalArgumentException("parent token must not be null");
7760            }
7761            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7762            if (r == null) {
7763                return null;
7764            }
7765            if (callback == null) {
7766                throw new IllegalArgumentException("callback must not be null");
7767            }
7768            return mStackSupervisor.createActivityContainer(r, callback);
7769        }
7770    }
7771
7772    @Override
7773    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7774        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7775                "deleteActivityContainer()");
7776        synchronized (this) {
7777            mStackSupervisor.deleteActivityContainer(container);
7778        }
7779    }
7780
7781    @Override
7782    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7783            throws RemoteException {
7784        synchronized (this) {
7785            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7786            if (stack != null) {
7787                return stack.mActivityContainer;
7788            }
7789            return null;
7790        }
7791    }
7792
7793    @Override
7794    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7795        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7796                "moveTaskToStack()");
7797        if (stackId == HOME_STACK_ID) {
7798            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7799                    new RuntimeException("here").fillInStackTrace());
7800        }
7801        synchronized (this) {
7802            long ident = Binder.clearCallingIdentity();
7803            try {
7804                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7805                        + stackId + " toTop=" + toTop);
7806                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7807            } finally {
7808                Binder.restoreCallingIdentity(ident);
7809            }
7810        }
7811    }
7812
7813    @Override
7814    public void resizeStack(int stackBoxId, Rect bounds) {
7815        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7816                "resizeStackBox()");
7817        long ident = Binder.clearCallingIdentity();
7818        try {
7819            mWindowManager.resizeStack(stackBoxId, bounds);
7820        } finally {
7821            Binder.restoreCallingIdentity(ident);
7822        }
7823    }
7824
7825    @Override
7826    public List<StackInfo> getAllStackInfos() {
7827        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7828                "getAllStackInfos()");
7829        long ident = Binder.clearCallingIdentity();
7830        try {
7831            synchronized (this) {
7832                return mStackSupervisor.getAllStackInfosLocked();
7833            }
7834        } finally {
7835            Binder.restoreCallingIdentity(ident);
7836        }
7837    }
7838
7839    @Override
7840    public StackInfo getStackInfo(int stackId) {
7841        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7842                "getStackInfo()");
7843        long ident = Binder.clearCallingIdentity();
7844        try {
7845            synchronized (this) {
7846                return mStackSupervisor.getStackInfoLocked(stackId);
7847            }
7848        } finally {
7849            Binder.restoreCallingIdentity(ident);
7850        }
7851    }
7852
7853    @Override
7854    public boolean isInHomeStack(int taskId) {
7855        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7856                "getStackInfo()");
7857        long ident = Binder.clearCallingIdentity();
7858        try {
7859            synchronized (this) {
7860                TaskRecord tr = recentTaskForIdLocked(taskId);
7861                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7862            }
7863        } finally {
7864            Binder.restoreCallingIdentity(ident);
7865        }
7866    }
7867
7868    @Override
7869    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7870        synchronized(this) {
7871            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7872        }
7873    }
7874
7875    private boolean isLockTaskAuthorized(String pkg) {
7876        final DevicePolicyManager dpm = (DevicePolicyManager)
7877                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7878        try {
7879            int uid = mContext.getPackageManager().getPackageUid(pkg,
7880                    Binder.getCallingUserHandle().getIdentifier());
7881            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7882        } catch (NameNotFoundException e) {
7883            return false;
7884        }
7885    }
7886
7887    void startLockTaskMode(TaskRecord task) {
7888        final String pkg;
7889        synchronized (this) {
7890            pkg = task.intent.getComponent().getPackageName();
7891        }
7892        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7893        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7894            final TaskRecord taskRecord = task;
7895            mHandler.post(new Runnable() {
7896                @Override
7897                public void run() {
7898                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7899                }
7900            });
7901            return;
7902        }
7903        long ident = Binder.clearCallingIdentity();
7904        try {
7905            synchronized (this) {
7906                // Since we lost lock on task, make sure it is still there.
7907                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7908                if (task != null) {
7909                    if (!isSystemInitiated
7910                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7911                        throw new IllegalArgumentException("Invalid task, not in foreground");
7912                    }
7913                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7914                }
7915            }
7916        } finally {
7917            Binder.restoreCallingIdentity(ident);
7918        }
7919    }
7920
7921    @Override
7922    public void startLockTaskMode(int taskId) {
7923        final TaskRecord task;
7924        long ident = Binder.clearCallingIdentity();
7925        try {
7926            synchronized (this) {
7927                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7928            }
7929        } finally {
7930            Binder.restoreCallingIdentity(ident);
7931        }
7932        if (task != null) {
7933            startLockTaskMode(task);
7934        }
7935    }
7936
7937    @Override
7938    public void startLockTaskMode(IBinder token) {
7939        final TaskRecord task;
7940        long ident = Binder.clearCallingIdentity();
7941        try {
7942            synchronized (this) {
7943                final ActivityRecord r = ActivityRecord.forToken(token);
7944                if (r == null) {
7945                    return;
7946                }
7947                task = r.task;
7948            }
7949        } finally {
7950            Binder.restoreCallingIdentity(ident);
7951        }
7952        if (task != null) {
7953            startLockTaskMode(task);
7954        }
7955    }
7956
7957    @Override
7958    public void startLockTaskModeOnCurrent() throws RemoteException {
7959        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7960        ActivityRecord r = null;
7961        synchronized (this) {
7962            r = mStackSupervisor.topRunningActivityLocked();
7963        }
7964        startLockTaskMode(r.task);
7965    }
7966
7967    @Override
7968    public void stopLockTaskMode() {
7969        // Verify that the user matches the package of the intent for the TaskRecord
7970        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7971        // and stopLockTaskMode.
7972        final int callingUid = Binder.getCallingUid();
7973        if (callingUid != Process.SYSTEM_UID) {
7974            try {
7975                String pkg =
7976                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7977                int uid = mContext.getPackageManager().getPackageUid(pkg,
7978                        Binder.getCallingUserHandle().getIdentifier());
7979                if (uid != callingUid) {
7980                    throw new SecurityException("Invalid uid, expected " + uid);
7981                }
7982            } catch (NameNotFoundException e) {
7983                Log.d(TAG, "stopLockTaskMode " + e);
7984                return;
7985            }
7986        }
7987        long ident = Binder.clearCallingIdentity();
7988        try {
7989            Log.d(TAG, "stopLockTaskMode");
7990            // Stop lock task
7991            synchronized (this) {
7992                mStackSupervisor.setLockTaskModeLocked(null, false);
7993            }
7994        } finally {
7995            Binder.restoreCallingIdentity(ident);
7996        }
7997    }
7998
7999    @Override
8000    public void stopLockTaskModeOnCurrent() throws RemoteException {
8001        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8002        long ident = Binder.clearCallingIdentity();
8003        try {
8004            stopLockTaskMode();
8005        } finally {
8006            Binder.restoreCallingIdentity(ident);
8007        }
8008    }
8009
8010    @Override
8011    public boolean isInLockTaskMode() {
8012        synchronized (this) {
8013            return mStackSupervisor.isInLockTaskMode();
8014        }
8015    }
8016
8017    // =========================================================
8018    // CONTENT PROVIDERS
8019    // =========================================================
8020
8021    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8022        List<ProviderInfo> providers = null;
8023        try {
8024            providers = AppGlobals.getPackageManager().
8025                queryContentProviders(app.processName, app.uid,
8026                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8027        } catch (RemoteException ex) {
8028        }
8029        if (DEBUG_MU)
8030            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8031        int userId = app.userId;
8032        if (providers != null) {
8033            int N = providers.size();
8034            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8035            for (int i=0; i<N; i++) {
8036                ProviderInfo cpi =
8037                    (ProviderInfo)providers.get(i);
8038                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8039                        cpi.name, cpi.flags);
8040                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8041                    // This is a singleton provider, but a user besides the
8042                    // default user is asking to initialize a process it runs
8043                    // in...  well, no, it doesn't actually run in this process,
8044                    // it runs in the process of the default user.  Get rid of it.
8045                    providers.remove(i);
8046                    N--;
8047                    i--;
8048                    continue;
8049                }
8050
8051                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8052                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8053                if (cpr == null) {
8054                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8055                    mProviderMap.putProviderByClass(comp, cpr);
8056                }
8057                if (DEBUG_MU)
8058                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8059                app.pubProviders.put(cpi.name, cpr);
8060                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8061                    // Don't add this if it is a platform component that is marked
8062                    // to run in multiple processes, because this is actually
8063                    // part of the framework so doesn't make sense to track as a
8064                    // separate apk in the process.
8065                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8066                            mProcessStats);
8067                }
8068                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8069            }
8070        }
8071        return providers;
8072    }
8073
8074    /**
8075     * Check if {@link ProcessRecord} has a possible chance at accessing the
8076     * given {@link ProviderInfo}. Final permission checking is always done
8077     * in {@link ContentProvider}.
8078     */
8079    private final String checkContentProviderPermissionLocked(
8080            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8081        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8082        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8083        boolean checkedGrants = false;
8084        if (checkUser) {
8085            // Looking for cross-user grants before enforcing the typical cross-users permissions
8086            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8087            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8088                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8089                    return null;
8090                }
8091                checkedGrants = true;
8092            }
8093            userId = handleIncomingUser(callingPid, callingUid, userId,
8094                    false, ALLOW_NON_FULL,
8095                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8096            if (userId != tmpTargetUserId) {
8097                // When we actually went to determine the final targer user ID, this ended
8098                // up different than our initial check for the authority.  This is because
8099                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8100                // SELF.  So we need to re-check the grants again.
8101                checkedGrants = false;
8102            }
8103        }
8104        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8105                cpi.applicationInfo.uid, cpi.exported)
8106                == PackageManager.PERMISSION_GRANTED) {
8107            return null;
8108        }
8109        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8110                cpi.applicationInfo.uid, cpi.exported)
8111                == PackageManager.PERMISSION_GRANTED) {
8112            return null;
8113        }
8114
8115        PathPermission[] pps = cpi.pathPermissions;
8116        if (pps != null) {
8117            int i = pps.length;
8118            while (i > 0) {
8119                i--;
8120                PathPermission pp = pps[i];
8121                String pprperm = pp.getReadPermission();
8122                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8123                        cpi.applicationInfo.uid, cpi.exported)
8124                        == PackageManager.PERMISSION_GRANTED) {
8125                    return null;
8126                }
8127                String ppwperm = pp.getWritePermission();
8128                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8129                        cpi.applicationInfo.uid, cpi.exported)
8130                        == PackageManager.PERMISSION_GRANTED) {
8131                    return null;
8132                }
8133            }
8134        }
8135        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8136            return null;
8137        }
8138
8139        String msg;
8140        if (!cpi.exported) {
8141            msg = "Permission Denial: opening provider " + cpi.name
8142                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8143                    + ", uid=" + callingUid + ") that is not exported from uid "
8144                    + cpi.applicationInfo.uid;
8145        } else {
8146            msg = "Permission Denial: opening provider " + cpi.name
8147                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8148                    + ", uid=" + callingUid + ") requires "
8149                    + cpi.readPermission + " or " + cpi.writePermission;
8150        }
8151        Slog.w(TAG, msg);
8152        return msg;
8153    }
8154
8155    /**
8156     * Returns if the ContentProvider has granted a uri to callingUid
8157     */
8158    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8159        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8160        if (perms != null) {
8161            for (int i=perms.size()-1; i>=0; i--) {
8162                GrantUri grantUri = perms.keyAt(i);
8163                if (grantUri.sourceUserId == userId || !checkUser) {
8164                    if (matchesProvider(grantUri.uri, cpi)) {
8165                        return true;
8166                    }
8167                }
8168            }
8169        }
8170        return false;
8171    }
8172
8173    /**
8174     * Returns true if the uri authority is one of the authorities specified in the provider.
8175     */
8176    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8177        String uriAuth = uri.getAuthority();
8178        String cpiAuth = cpi.authority;
8179        if (cpiAuth.indexOf(';') == -1) {
8180            return cpiAuth.equals(uriAuth);
8181        }
8182        String[] cpiAuths = cpiAuth.split(";");
8183        int length = cpiAuths.length;
8184        for (int i = 0; i < length; i++) {
8185            if (cpiAuths[i].equals(uriAuth)) return true;
8186        }
8187        return false;
8188    }
8189
8190    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8191            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8192        if (r != null) {
8193            for (int i=0; i<r.conProviders.size(); i++) {
8194                ContentProviderConnection conn = r.conProviders.get(i);
8195                if (conn.provider == cpr) {
8196                    if (DEBUG_PROVIDER) Slog.v(TAG,
8197                            "Adding provider requested by "
8198                            + r.processName + " from process "
8199                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8200                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8201                    if (stable) {
8202                        conn.stableCount++;
8203                        conn.numStableIncs++;
8204                    } else {
8205                        conn.unstableCount++;
8206                        conn.numUnstableIncs++;
8207                    }
8208                    return conn;
8209                }
8210            }
8211            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8212            if (stable) {
8213                conn.stableCount = 1;
8214                conn.numStableIncs = 1;
8215            } else {
8216                conn.unstableCount = 1;
8217                conn.numUnstableIncs = 1;
8218            }
8219            cpr.connections.add(conn);
8220            r.conProviders.add(conn);
8221            return conn;
8222        }
8223        cpr.addExternalProcessHandleLocked(externalProcessToken);
8224        return null;
8225    }
8226
8227    boolean decProviderCountLocked(ContentProviderConnection conn,
8228            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8229        if (conn != null) {
8230            cpr = conn.provider;
8231            if (DEBUG_PROVIDER) Slog.v(TAG,
8232                    "Removing provider requested by "
8233                    + conn.client.processName + " from process "
8234                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8235                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8236            if (stable) {
8237                conn.stableCount--;
8238            } else {
8239                conn.unstableCount--;
8240            }
8241            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8242                cpr.connections.remove(conn);
8243                conn.client.conProviders.remove(conn);
8244                return true;
8245            }
8246            return false;
8247        }
8248        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8249        return false;
8250    }
8251
8252    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8253            String name, IBinder token, boolean stable, int userId) {
8254        ContentProviderRecord cpr;
8255        ContentProviderConnection conn = null;
8256        ProviderInfo cpi = null;
8257
8258        synchronized(this) {
8259            ProcessRecord r = null;
8260            if (caller != null) {
8261                r = getRecordForAppLocked(caller);
8262                if (r == null) {
8263                    throw new SecurityException(
8264                            "Unable to find app for caller " + caller
8265                          + " (pid=" + Binder.getCallingPid()
8266                          + ") when getting content provider " + name);
8267                }
8268            }
8269
8270            boolean checkCrossUser = true;
8271
8272            // First check if this content provider has been published...
8273            cpr = mProviderMap.getProviderByName(name, userId);
8274            // If that didn't work, check if it exists for user 0 and then
8275            // verify that it's a singleton provider before using it.
8276            if (cpr == null && userId != UserHandle.USER_OWNER) {
8277                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8278                if (cpr != null) {
8279                    cpi = cpr.info;
8280                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8281                            cpi.name, cpi.flags)
8282                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8283                        userId = UserHandle.USER_OWNER;
8284                        checkCrossUser = false;
8285                    } else {
8286                        cpr = null;
8287                        cpi = null;
8288                    }
8289                }
8290            }
8291
8292            boolean providerRunning = cpr != null;
8293            if (providerRunning) {
8294                cpi = cpr.info;
8295                String msg;
8296                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8297                        != null) {
8298                    throw new SecurityException(msg);
8299                }
8300
8301                if (r != null && cpr.canRunHere(r)) {
8302                    // This provider has been published or is in the process
8303                    // of being published...  but it is also allowed to run
8304                    // in the caller's process, so don't make a connection
8305                    // and just let the caller instantiate its own instance.
8306                    ContentProviderHolder holder = cpr.newHolder(null);
8307                    // don't give caller the provider object, it needs
8308                    // to make its own.
8309                    holder.provider = null;
8310                    return holder;
8311                }
8312
8313                final long origId = Binder.clearCallingIdentity();
8314
8315                // In this case the provider instance already exists, so we can
8316                // return it right away.
8317                conn = incProviderCountLocked(r, cpr, token, stable);
8318                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8319                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8320                        // If this is a perceptible app accessing the provider,
8321                        // make sure to count it as being accessed and thus
8322                        // back up on the LRU list.  This is good because
8323                        // content providers are often expensive to start.
8324                        updateLruProcessLocked(cpr.proc, false, null);
8325                    }
8326                }
8327
8328                if (cpr.proc != null) {
8329                    if (false) {
8330                        if (cpr.name.flattenToShortString().equals(
8331                                "com.android.providers.calendar/.CalendarProvider2")) {
8332                            Slog.v(TAG, "****************** KILLING "
8333                                + cpr.name.flattenToShortString());
8334                            Process.killProcess(cpr.proc.pid);
8335                        }
8336                    }
8337                    boolean success = updateOomAdjLocked(cpr.proc);
8338                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8339                    // NOTE: there is still a race here where a signal could be
8340                    // pending on the process even though we managed to update its
8341                    // adj level.  Not sure what to do about this, but at least
8342                    // the race is now smaller.
8343                    if (!success) {
8344                        // Uh oh...  it looks like the provider's process
8345                        // has been killed on us.  We need to wait for a new
8346                        // process to be started, and make sure its death
8347                        // doesn't kill our process.
8348                        Slog.i(TAG,
8349                                "Existing provider " + cpr.name.flattenToShortString()
8350                                + " is crashing; detaching " + r);
8351                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8352                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8353                        if (!lastRef) {
8354                            // This wasn't the last ref our process had on
8355                            // the provider...  we have now been killed, bail.
8356                            return null;
8357                        }
8358                        providerRunning = false;
8359                        conn = null;
8360                    }
8361                }
8362
8363                Binder.restoreCallingIdentity(origId);
8364            }
8365
8366            boolean singleton;
8367            if (!providerRunning) {
8368                try {
8369                    cpi = AppGlobals.getPackageManager().
8370                        resolveContentProvider(name,
8371                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8372                } catch (RemoteException ex) {
8373                }
8374                if (cpi == null) {
8375                    return null;
8376                }
8377                // If the provider is a singleton AND
8378                // (it's a call within the same user || the provider is a
8379                // privileged app)
8380                // Then allow connecting to the singleton provider
8381                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8382                        cpi.name, cpi.flags)
8383                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8384                if (singleton) {
8385                    userId = UserHandle.USER_OWNER;
8386                }
8387                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8388
8389                String msg;
8390                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8391                        != null) {
8392                    throw new SecurityException(msg);
8393                }
8394
8395                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8396                        && !cpi.processName.equals("system")) {
8397                    // If this content provider does not run in the system
8398                    // process, and the system is not yet ready to run other
8399                    // processes, then fail fast instead of hanging.
8400                    throw new IllegalArgumentException(
8401                            "Attempt to launch content provider before system ready");
8402                }
8403
8404                // Make sure that the user who owns this provider is started.  If not,
8405                // we don't want to allow it to run.
8406                if (mStartedUsers.get(userId) == null) {
8407                    Slog.w(TAG, "Unable to launch app "
8408                            + cpi.applicationInfo.packageName + "/"
8409                            + cpi.applicationInfo.uid + " for provider "
8410                            + name + ": user " + userId + " is stopped");
8411                    return null;
8412                }
8413
8414                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8415                cpr = mProviderMap.getProviderByClass(comp, userId);
8416                final boolean firstClass = cpr == null;
8417                if (firstClass) {
8418                    try {
8419                        ApplicationInfo ai =
8420                            AppGlobals.getPackageManager().
8421                                getApplicationInfo(
8422                                        cpi.applicationInfo.packageName,
8423                                        STOCK_PM_FLAGS, userId);
8424                        if (ai == null) {
8425                            Slog.w(TAG, "No package info for content provider "
8426                                    + cpi.name);
8427                            return null;
8428                        }
8429                        ai = getAppInfoForUser(ai, userId);
8430                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8431                    } catch (RemoteException ex) {
8432                        // pm is in same process, this will never happen.
8433                    }
8434                }
8435
8436                if (r != null && cpr.canRunHere(r)) {
8437                    // If this is a multiprocess provider, then just return its
8438                    // info and allow the caller to instantiate it.  Only do
8439                    // this if the provider is the same user as the caller's
8440                    // process, or can run as root (so can be in any process).
8441                    return cpr.newHolder(null);
8442                }
8443
8444                if (DEBUG_PROVIDER) {
8445                    RuntimeException e = new RuntimeException("here");
8446                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8447                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8448                }
8449
8450                // This is single process, and our app is now connecting to it.
8451                // See if we are already in the process of launching this
8452                // provider.
8453                final int N = mLaunchingProviders.size();
8454                int i;
8455                for (i=0; i<N; i++) {
8456                    if (mLaunchingProviders.get(i) == cpr) {
8457                        break;
8458                    }
8459                }
8460
8461                // If the provider is not already being launched, then get it
8462                // started.
8463                if (i >= N) {
8464                    final long origId = Binder.clearCallingIdentity();
8465
8466                    try {
8467                        // Content provider is now in use, its package can't be stopped.
8468                        try {
8469                            AppGlobals.getPackageManager().setPackageStoppedState(
8470                                    cpr.appInfo.packageName, false, userId);
8471                        } catch (RemoteException e) {
8472                        } catch (IllegalArgumentException e) {
8473                            Slog.w(TAG, "Failed trying to unstop package "
8474                                    + cpr.appInfo.packageName + ": " + e);
8475                        }
8476
8477                        // Use existing process if already started
8478                        ProcessRecord proc = getProcessRecordLocked(
8479                                cpi.processName, cpr.appInfo.uid, false);
8480                        if (proc != null && proc.thread != null) {
8481                            if (DEBUG_PROVIDER) {
8482                                Slog.d(TAG, "Installing in existing process " + proc);
8483                            }
8484                            proc.pubProviders.put(cpi.name, cpr);
8485                            try {
8486                                proc.thread.scheduleInstallProvider(cpi);
8487                            } catch (RemoteException e) {
8488                            }
8489                        } else {
8490                            proc = startProcessLocked(cpi.processName,
8491                                    cpr.appInfo, false, 0, "content provider",
8492                                    new ComponentName(cpi.applicationInfo.packageName,
8493                                            cpi.name), false, false, false);
8494                            if (proc == null) {
8495                                Slog.w(TAG, "Unable to launch app "
8496                                        + cpi.applicationInfo.packageName + "/"
8497                                        + cpi.applicationInfo.uid + " for provider "
8498                                        + name + ": process is bad");
8499                                return null;
8500                            }
8501                        }
8502                        cpr.launchingApp = proc;
8503                        mLaunchingProviders.add(cpr);
8504                    } finally {
8505                        Binder.restoreCallingIdentity(origId);
8506                    }
8507                }
8508
8509                // Make sure the provider is published (the same provider class
8510                // may be published under multiple names).
8511                if (firstClass) {
8512                    mProviderMap.putProviderByClass(comp, cpr);
8513                }
8514
8515                mProviderMap.putProviderByName(name, cpr);
8516                conn = incProviderCountLocked(r, cpr, token, stable);
8517                if (conn != null) {
8518                    conn.waiting = true;
8519                }
8520            }
8521        }
8522
8523        // Wait for the provider to be published...
8524        synchronized (cpr) {
8525            while (cpr.provider == null) {
8526                if (cpr.launchingApp == null) {
8527                    Slog.w(TAG, "Unable to launch app "
8528                            + cpi.applicationInfo.packageName + "/"
8529                            + cpi.applicationInfo.uid + " for provider "
8530                            + name + ": launching app became null");
8531                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8532                            UserHandle.getUserId(cpi.applicationInfo.uid),
8533                            cpi.applicationInfo.packageName,
8534                            cpi.applicationInfo.uid, name);
8535                    return null;
8536                }
8537                try {
8538                    if (DEBUG_MU) {
8539                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8540                                + cpr.launchingApp);
8541                    }
8542                    if (conn != null) {
8543                        conn.waiting = true;
8544                    }
8545                    cpr.wait();
8546                } catch (InterruptedException ex) {
8547                } finally {
8548                    if (conn != null) {
8549                        conn.waiting = false;
8550                    }
8551                }
8552            }
8553        }
8554        return cpr != null ? cpr.newHolder(conn) : null;
8555    }
8556
8557    @Override
8558    public final ContentProviderHolder getContentProvider(
8559            IApplicationThread caller, String name, int userId, boolean stable) {
8560        enforceNotIsolatedCaller("getContentProvider");
8561        if (caller == null) {
8562            String msg = "null IApplicationThread when getting content provider "
8563                    + name;
8564            Slog.w(TAG, msg);
8565            throw new SecurityException(msg);
8566        }
8567        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8568        // with cross-user grant.
8569        return getContentProviderImpl(caller, name, null, stable, userId);
8570    }
8571
8572    public ContentProviderHolder getContentProviderExternal(
8573            String name, int userId, IBinder token) {
8574        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8575            "Do not have permission in call getContentProviderExternal()");
8576        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8577                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8578        return getContentProviderExternalUnchecked(name, token, userId);
8579    }
8580
8581    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8582            IBinder token, int userId) {
8583        return getContentProviderImpl(null, name, token, true, userId);
8584    }
8585
8586    /**
8587     * Drop a content provider from a ProcessRecord's bookkeeping
8588     */
8589    public void removeContentProvider(IBinder connection, boolean stable) {
8590        enforceNotIsolatedCaller("removeContentProvider");
8591        long ident = Binder.clearCallingIdentity();
8592        try {
8593            synchronized (this) {
8594                ContentProviderConnection conn;
8595                try {
8596                    conn = (ContentProviderConnection)connection;
8597                } catch (ClassCastException e) {
8598                    String msg ="removeContentProvider: " + connection
8599                            + " not a ContentProviderConnection";
8600                    Slog.w(TAG, msg);
8601                    throw new IllegalArgumentException(msg);
8602                }
8603                if (conn == null) {
8604                    throw new NullPointerException("connection is null");
8605                }
8606                if (decProviderCountLocked(conn, null, null, stable)) {
8607                    updateOomAdjLocked();
8608                }
8609            }
8610        } finally {
8611            Binder.restoreCallingIdentity(ident);
8612        }
8613    }
8614
8615    public void removeContentProviderExternal(String name, IBinder token) {
8616        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8617            "Do not have permission in call removeContentProviderExternal()");
8618        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8619    }
8620
8621    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8622        synchronized (this) {
8623            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8624            if(cpr == null) {
8625                //remove from mProvidersByClass
8626                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8627                return;
8628            }
8629
8630            //update content provider record entry info
8631            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8632            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8633            if (localCpr.hasExternalProcessHandles()) {
8634                if (localCpr.removeExternalProcessHandleLocked(token)) {
8635                    updateOomAdjLocked();
8636                } else {
8637                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8638                            + " with no external reference for token: "
8639                            + token + ".");
8640                }
8641            } else {
8642                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8643                        + " with no external references.");
8644            }
8645        }
8646    }
8647
8648    public final void publishContentProviders(IApplicationThread caller,
8649            List<ContentProviderHolder> providers) {
8650        if (providers == null) {
8651            return;
8652        }
8653
8654        enforceNotIsolatedCaller("publishContentProviders");
8655        synchronized (this) {
8656            final ProcessRecord r = getRecordForAppLocked(caller);
8657            if (DEBUG_MU)
8658                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8659            if (r == null) {
8660                throw new SecurityException(
8661                        "Unable to find app for caller " + caller
8662                      + " (pid=" + Binder.getCallingPid()
8663                      + ") when publishing content providers");
8664            }
8665
8666            final long origId = Binder.clearCallingIdentity();
8667
8668            final int N = providers.size();
8669            for (int i=0; i<N; i++) {
8670                ContentProviderHolder src = providers.get(i);
8671                if (src == null || src.info == null || src.provider == null) {
8672                    continue;
8673                }
8674                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8675                if (DEBUG_MU)
8676                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8677                if (dst != null) {
8678                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8679                    mProviderMap.putProviderByClass(comp, dst);
8680                    String names[] = dst.info.authority.split(";");
8681                    for (int j = 0; j < names.length; j++) {
8682                        mProviderMap.putProviderByName(names[j], dst);
8683                    }
8684
8685                    int NL = mLaunchingProviders.size();
8686                    int j;
8687                    for (j=0; j<NL; j++) {
8688                        if (mLaunchingProviders.get(j) == dst) {
8689                            mLaunchingProviders.remove(j);
8690                            j--;
8691                            NL--;
8692                        }
8693                    }
8694                    synchronized (dst) {
8695                        dst.provider = src.provider;
8696                        dst.proc = r;
8697                        dst.notifyAll();
8698                    }
8699                    updateOomAdjLocked(r);
8700                }
8701            }
8702
8703            Binder.restoreCallingIdentity(origId);
8704        }
8705    }
8706
8707    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8708        ContentProviderConnection conn;
8709        try {
8710            conn = (ContentProviderConnection)connection;
8711        } catch (ClassCastException e) {
8712            String msg ="refContentProvider: " + connection
8713                    + " not a ContentProviderConnection";
8714            Slog.w(TAG, msg);
8715            throw new IllegalArgumentException(msg);
8716        }
8717        if (conn == null) {
8718            throw new NullPointerException("connection is null");
8719        }
8720
8721        synchronized (this) {
8722            if (stable > 0) {
8723                conn.numStableIncs += stable;
8724            }
8725            stable = conn.stableCount + stable;
8726            if (stable < 0) {
8727                throw new IllegalStateException("stableCount < 0: " + stable);
8728            }
8729
8730            if (unstable > 0) {
8731                conn.numUnstableIncs += unstable;
8732            }
8733            unstable = conn.unstableCount + unstable;
8734            if (unstable < 0) {
8735                throw new IllegalStateException("unstableCount < 0: " + unstable);
8736            }
8737
8738            if ((stable+unstable) <= 0) {
8739                throw new IllegalStateException("ref counts can't go to zero here: stable="
8740                        + stable + " unstable=" + unstable);
8741            }
8742            conn.stableCount = stable;
8743            conn.unstableCount = unstable;
8744            return !conn.dead;
8745        }
8746    }
8747
8748    public void unstableProviderDied(IBinder connection) {
8749        ContentProviderConnection conn;
8750        try {
8751            conn = (ContentProviderConnection)connection;
8752        } catch (ClassCastException e) {
8753            String msg ="refContentProvider: " + connection
8754                    + " not a ContentProviderConnection";
8755            Slog.w(TAG, msg);
8756            throw new IllegalArgumentException(msg);
8757        }
8758        if (conn == null) {
8759            throw new NullPointerException("connection is null");
8760        }
8761
8762        // Safely retrieve the content provider associated with the connection.
8763        IContentProvider provider;
8764        synchronized (this) {
8765            provider = conn.provider.provider;
8766        }
8767
8768        if (provider == null) {
8769            // Um, yeah, we're way ahead of you.
8770            return;
8771        }
8772
8773        // Make sure the caller is being honest with us.
8774        if (provider.asBinder().pingBinder()) {
8775            // Er, no, still looks good to us.
8776            synchronized (this) {
8777                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8778                        + " says " + conn + " died, but we don't agree");
8779                return;
8780            }
8781        }
8782
8783        // Well look at that!  It's dead!
8784        synchronized (this) {
8785            if (conn.provider.provider != provider) {
8786                // But something changed...  good enough.
8787                return;
8788            }
8789
8790            ProcessRecord proc = conn.provider.proc;
8791            if (proc == null || proc.thread == null) {
8792                // Seems like the process is already cleaned up.
8793                return;
8794            }
8795
8796            // As far as we're concerned, this is just like receiving a
8797            // death notification...  just a bit prematurely.
8798            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8799                    + ") early provider death");
8800            final long ident = Binder.clearCallingIdentity();
8801            try {
8802                appDiedLocked(proc, proc.pid, proc.thread);
8803            } finally {
8804                Binder.restoreCallingIdentity(ident);
8805            }
8806        }
8807    }
8808
8809    @Override
8810    public void appNotRespondingViaProvider(IBinder connection) {
8811        enforceCallingPermission(
8812                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8813
8814        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8815        if (conn == null) {
8816            Slog.w(TAG, "ContentProviderConnection is null");
8817            return;
8818        }
8819
8820        final ProcessRecord host = conn.provider.proc;
8821        if (host == null) {
8822            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8823            return;
8824        }
8825
8826        final long token = Binder.clearCallingIdentity();
8827        try {
8828            appNotResponding(host, null, null, false, "ContentProvider not responding");
8829        } finally {
8830            Binder.restoreCallingIdentity(token);
8831        }
8832    }
8833
8834    public final void installSystemProviders() {
8835        List<ProviderInfo> providers;
8836        synchronized (this) {
8837            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8838            providers = generateApplicationProvidersLocked(app);
8839            if (providers != null) {
8840                for (int i=providers.size()-1; i>=0; i--) {
8841                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8842                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8843                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8844                                + ": not system .apk");
8845                        providers.remove(i);
8846                    }
8847                }
8848            }
8849        }
8850        if (providers != null) {
8851            mSystemThread.installSystemProviders(providers);
8852        }
8853
8854        mCoreSettingsObserver = new CoreSettingsObserver(this);
8855
8856        //mUsageStatsService.monitorPackages();
8857    }
8858
8859    /**
8860     * Allows app to retrieve the MIME type of a URI without having permission
8861     * to access its content provider.
8862     *
8863     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8864     *
8865     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8866     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8867     */
8868    public String getProviderMimeType(Uri uri, int userId) {
8869        enforceNotIsolatedCaller("getProviderMimeType");
8870        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8871                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8872        final String name = uri.getAuthority();
8873        final long ident = Binder.clearCallingIdentity();
8874        ContentProviderHolder holder = null;
8875
8876        try {
8877            holder = getContentProviderExternalUnchecked(name, null, userId);
8878            if (holder != null) {
8879                return holder.provider.getType(uri);
8880            }
8881        } catch (RemoteException e) {
8882            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8883            return null;
8884        } finally {
8885            if (holder != null) {
8886                removeContentProviderExternalUnchecked(name, null, userId);
8887            }
8888            Binder.restoreCallingIdentity(ident);
8889        }
8890
8891        return null;
8892    }
8893
8894    // =========================================================
8895    // GLOBAL MANAGEMENT
8896    // =========================================================
8897
8898    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8899            boolean isolated) {
8900        String proc = customProcess != null ? customProcess : info.processName;
8901        BatteryStatsImpl.Uid.Proc ps = null;
8902        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8903        int uid = info.uid;
8904        if (isolated) {
8905            int userId = UserHandle.getUserId(uid);
8906            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8907            while (true) {
8908                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8909                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8910                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8911                }
8912                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8913                mNextIsolatedProcessUid++;
8914                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8915                    // No process for this uid, use it.
8916                    break;
8917                }
8918                stepsLeft--;
8919                if (stepsLeft <= 0) {
8920                    return null;
8921                }
8922            }
8923        }
8924        return new ProcessRecord(stats, info, proc, uid);
8925    }
8926
8927    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8928            String abiOverride) {
8929        ProcessRecord app;
8930        if (!isolated) {
8931            app = getProcessRecordLocked(info.processName, info.uid, true);
8932        } else {
8933            app = null;
8934        }
8935
8936        if (app == null) {
8937            app = newProcessRecordLocked(info, null, isolated);
8938            mProcessNames.put(info.processName, app.uid, app);
8939            if (isolated) {
8940                mIsolatedProcesses.put(app.uid, app);
8941            }
8942            updateLruProcessLocked(app, false, null);
8943            updateOomAdjLocked();
8944        }
8945
8946        // This package really, really can not be stopped.
8947        try {
8948            AppGlobals.getPackageManager().setPackageStoppedState(
8949                    info.packageName, false, UserHandle.getUserId(app.uid));
8950        } catch (RemoteException e) {
8951        } catch (IllegalArgumentException e) {
8952            Slog.w(TAG, "Failed trying to unstop package "
8953                    + info.packageName + ": " + e);
8954        }
8955
8956        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8957                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8958            app.persistent = true;
8959            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8960        }
8961        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8962            mPersistentStartingProcesses.add(app);
8963            startProcessLocked(app, "added application", app.processName,
8964                    abiOverride);
8965        }
8966
8967        return app;
8968    }
8969
8970    public void unhandledBack() {
8971        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8972                "unhandledBack()");
8973
8974        synchronized(this) {
8975            final long origId = Binder.clearCallingIdentity();
8976            try {
8977                getFocusedStack().unhandledBackLocked();
8978            } finally {
8979                Binder.restoreCallingIdentity(origId);
8980            }
8981        }
8982    }
8983
8984    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8985        enforceNotIsolatedCaller("openContentUri");
8986        final int userId = UserHandle.getCallingUserId();
8987        String name = uri.getAuthority();
8988        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8989        ParcelFileDescriptor pfd = null;
8990        if (cph != null) {
8991            // We record the binder invoker's uid in thread-local storage before
8992            // going to the content provider to open the file.  Later, in the code
8993            // that handles all permissions checks, we look for this uid and use
8994            // that rather than the Activity Manager's own uid.  The effect is that
8995            // we do the check against the caller's permissions even though it looks
8996            // to the content provider like the Activity Manager itself is making
8997            // the request.
8998            sCallerIdentity.set(new Identity(
8999                    Binder.getCallingPid(), Binder.getCallingUid()));
9000            try {
9001                pfd = cph.provider.openFile(null, uri, "r", null);
9002            } catch (FileNotFoundException e) {
9003                // do nothing; pfd will be returned null
9004            } finally {
9005                // Ensure that whatever happens, we clean up the identity state
9006                sCallerIdentity.remove();
9007            }
9008
9009            // We've got the fd now, so we're done with the provider.
9010            removeContentProviderExternalUnchecked(name, null, userId);
9011        } else {
9012            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9013        }
9014        return pfd;
9015    }
9016
9017    // Actually is sleeping or shutting down or whatever else in the future
9018    // is an inactive state.
9019    public boolean isSleepingOrShuttingDown() {
9020        return mSleeping || mShuttingDown;
9021    }
9022
9023    public boolean isSleeping() {
9024        return mSleeping;
9025    }
9026
9027    void goingToSleep() {
9028        synchronized(this) {
9029            mWentToSleep = true;
9030            updateEventDispatchingLocked();
9031            goToSleepIfNeededLocked();
9032        }
9033    }
9034
9035    void finishRunningVoiceLocked() {
9036        if (mRunningVoice) {
9037            mRunningVoice = false;
9038            goToSleepIfNeededLocked();
9039        }
9040    }
9041
9042    void goToSleepIfNeededLocked() {
9043        if (mWentToSleep && !mRunningVoice) {
9044            if (!mSleeping) {
9045                mSleeping = true;
9046                mStackSupervisor.goingToSleepLocked();
9047
9048                // Initialize the wake times of all processes.
9049                checkExcessivePowerUsageLocked(false);
9050                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9051                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9052                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9053            }
9054        }
9055    }
9056
9057    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9058        mTaskPersister.notify(task, flush);
9059    }
9060
9061    @Override
9062    public boolean shutdown(int timeout) {
9063        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9064                != PackageManager.PERMISSION_GRANTED) {
9065            throw new SecurityException("Requires permission "
9066                    + android.Manifest.permission.SHUTDOWN);
9067        }
9068
9069        boolean timedout = false;
9070
9071        synchronized(this) {
9072            mShuttingDown = true;
9073            updateEventDispatchingLocked();
9074            timedout = mStackSupervisor.shutdownLocked(timeout);
9075        }
9076
9077        mAppOpsService.shutdown();
9078        if (mUsageStatsService != null) {
9079            mUsageStatsService.prepareShutdown();
9080        }
9081        mBatteryStatsService.shutdown();
9082        synchronized (this) {
9083            mProcessStats.shutdownLocked();
9084        }
9085        notifyTaskPersisterLocked(null, true);
9086
9087        return timedout;
9088    }
9089
9090    public final void activitySlept(IBinder token) {
9091        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9092
9093        final long origId = Binder.clearCallingIdentity();
9094
9095        synchronized (this) {
9096            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9097            if (r != null) {
9098                mStackSupervisor.activitySleptLocked(r);
9099            }
9100        }
9101
9102        Binder.restoreCallingIdentity(origId);
9103    }
9104
9105    void logLockScreen(String msg) {
9106        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9107                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9108                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9109                mStackSupervisor.mDismissKeyguardOnNextActivity);
9110    }
9111
9112    private void comeOutOfSleepIfNeededLocked() {
9113        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9114            if (mSleeping) {
9115                mSleeping = false;
9116                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9117            }
9118        }
9119    }
9120
9121    void wakingUp() {
9122        synchronized(this) {
9123            mWentToSleep = false;
9124            updateEventDispatchingLocked();
9125            comeOutOfSleepIfNeededLocked();
9126        }
9127    }
9128
9129    void startRunningVoiceLocked() {
9130        if (!mRunningVoice) {
9131            mRunningVoice = true;
9132            comeOutOfSleepIfNeededLocked();
9133        }
9134    }
9135
9136    private void updateEventDispatchingLocked() {
9137        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9138    }
9139
9140    public void setLockScreenShown(boolean shown) {
9141        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9142                != PackageManager.PERMISSION_GRANTED) {
9143            throw new SecurityException("Requires permission "
9144                    + android.Manifest.permission.DEVICE_POWER);
9145        }
9146
9147        synchronized(this) {
9148            long ident = Binder.clearCallingIdentity();
9149            try {
9150                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9151                mLockScreenShown = shown;
9152                comeOutOfSleepIfNeededLocked();
9153            } finally {
9154                Binder.restoreCallingIdentity(ident);
9155            }
9156        }
9157    }
9158
9159    @Override
9160    public void stopAppSwitches() {
9161        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9162                != PackageManager.PERMISSION_GRANTED) {
9163            throw new SecurityException("Requires permission "
9164                    + android.Manifest.permission.STOP_APP_SWITCHES);
9165        }
9166
9167        synchronized(this) {
9168            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9169                    + APP_SWITCH_DELAY_TIME;
9170            mDidAppSwitch = false;
9171            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9172            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9173            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9174        }
9175    }
9176
9177    public void resumeAppSwitches() {
9178        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9179                != PackageManager.PERMISSION_GRANTED) {
9180            throw new SecurityException("Requires permission "
9181                    + android.Manifest.permission.STOP_APP_SWITCHES);
9182        }
9183
9184        synchronized(this) {
9185            // Note that we don't execute any pending app switches... we will
9186            // let those wait until either the timeout, or the next start
9187            // activity request.
9188            mAppSwitchesAllowedTime = 0;
9189        }
9190    }
9191
9192    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9193            String name) {
9194        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9195            return true;
9196        }
9197
9198        final int perm = checkComponentPermission(
9199                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9200                callingUid, -1, true);
9201        if (perm == PackageManager.PERMISSION_GRANTED) {
9202            return true;
9203        }
9204
9205        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9206        return false;
9207    }
9208
9209    public void setDebugApp(String packageName, boolean waitForDebugger,
9210            boolean persistent) {
9211        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9212                "setDebugApp()");
9213
9214        long ident = Binder.clearCallingIdentity();
9215        try {
9216            // Note that this is not really thread safe if there are multiple
9217            // callers into it at the same time, but that's not a situation we
9218            // care about.
9219            if (persistent) {
9220                final ContentResolver resolver = mContext.getContentResolver();
9221                Settings.Global.putString(
9222                    resolver, Settings.Global.DEBUG_APP,
9223                    packageName);
9224                Settings.Global.putInt(
9225                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9226                    waitForDebugger ? 1 : 0);
9227            }
9228
9229            synchronized (this) {
9230                if (!persistent) {
9231                    mOrigDebugApp = mDebugApp;
9232                    mOrigWaitForDebugger = mWaitForDebugger;
9233                }
9234                mDebugApp = packageName;
9235                mWaitForDebugger = waitForDebugger;
9236                mDebugTransient = !persistent;
9237                if (packageName != null) {
9238                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9239                            false, UserHandle.USER_ALL, "set debug app");
9240                }
9241            }
9242        } finally {
9243            Binder.restoreCallingIdentity(ident);
9244        }
9245    }
9246
9247    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9248        synchronized (this) {
9249            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9250            if (!isDebuggable) {
9251                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9252                    throw new SecurityException("Process not debuggable: " + app.packageName);
9253                }
9254            }
9255
9256            mOpenGlTraceApp = processName;
9257        }
9258    }
9259
9260    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9261            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9262        synchronized (this) {
9263            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9264            if (!isDebuggable) {
9265                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9266                    throw new SecurityException("Process not debuggable: " + app.packageName);
9267                }
9268            }
9269            mProfileApp = processName;
9270            mProfileFile = profileFile;
9271            if (mProfileFd != null) {
9272                try {
9273                    mProfileFd.close();
9274                } catch (IOException e) {
9275                }
9276                mProfileFd = null;
9277            }
9278            mProfileFd = profileFd;
9279            mProfileType = 0;
9280            mAutoStopProfiler = autoStopProfiler;
9281        }
9282    }
9283
9284    @Override
9285    public void setAlwaysFinish(boolean enabled) {
9286        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9287                "setAlwaysFinish()");
9288
9289        Settings.Global.putInt(
9290                mContext.getContentResolver(),
9291                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9292
9293        synchronized (this) {
9294            mAlwaysFinishActivities = enabled;
9295        }
9296    }
9297
9298    @Override
9299    public void setActivityController(IActivityController controller) {
9300        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9301                "setActivityController()");
9302        synchronized (this) {
9303            mController = controller;
9304            Watchdog.getInstance().setActivityController(controller);
9305        }
9306    }
9307
9308    @Override
9309    public void setUserIsMonkey(boolean userIsMonkey) {
9310        synchronized (this) {
9311            synchronized (mPidsSelfLocked) {
9312                final int callingPid = Binder.getCallingPid();
9313                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9314                if (precessRecord == null) {
9315                    throw new SecurityException("Unknown process: " + callingPid);
9316                }
9317                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9318                    throw new SecurityException("Only an instrumentation process "
9319                            + "with a UiAutomation can call setUserIsMonkey");
9320                }
9321            }
9322            mUserIsMonkey = userIsMonkey;
9323        }
9324    }
9325
9326    @Override
9327    public boolean isUserAMonkey() {
9328        synchronized (this) {
9329            // If there is a controller also implies the user is a monkey.
9330            return (mUserIsMonkey || mController != null);
9331        }
9332    }
9333
9334    public void requestBugReport() {
9335        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9336        SystemProperties.set("ctl.start", "bugreport");
9337    }
9338
9339    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9340        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9341    }
9342
9343    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9344        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9345            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9346        }
9347        return KEY_DISPATCHING_TIMEOUT;
9348    }
9349
9350    @Override
9351    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9352        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9353                != PackageManager.PERMISSION_GRANTED) {
9354            throw new SecurityException("Requires permission "
9355                    + android.Manifest.permission.FILTER_EVENTS);
9356        }
9357        ProcessRecord proc;
9358        long timeout;
9359        synchronized (this) {
9360            synchronized (mPidsSelfLocked) {
9361                proc = mPidsSelfLocked.get(pid);
9362            }
9363            timeout = getInputDispatchingTimeoutLocked(proc);
9364        }
9365
9366        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9367            return -1;
9368        }
9369
9370        return timeout;
9371    }
9372
9373    /**
9374     * Handle input dispatching timeouts.
9375     * Returns whether input dispatching should be aborted or not.
9376     */
9377    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9378            final ActivityRecord activity, final ActivityRecord parent,
9379            final boolean aboveSystem, String reason) {
9380        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9381                != PackageManager.PERMISSION_GRANTED) {
9382            throw new SecurityException("Requires permission "
9383                    + android.Manifest.permission.FILTER_EVENTS);
9384        }
9385
9386        final String annotation;
9387        if (reason == null) {
9388            annotation = "Input dispatching timed out";
9389        } else {
9390            annotation = "Input dispatching timed out (" + reason + ")";
9391        }
9392
9393        if (proc != null) {
9394            synchronized (this) {
9395                if (proc.debugging) {
9396                    return false;
9397                }
9398
9399                if (mDidDexOpt) {
9400                    // Give more time since we were dexopting.
9401                    mDidDexOpt = false;
9402                    return false;
9403                }
9404
9405                if (proc.instrumentationClass != null) {
9406                    Bundle info = new Bundle();
9407                    info.putString("shortMsg", "keyDispatchingTimedOut");
9408                    info.putString("longMsg", annotation);
9409                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9410                    return true;
9411                }
9412            }
9413            mHandler.post(new Runnable() {
9414                @Override
9415                public void run() {
9416                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9417                }
9418            });
9419        }
9420
9421        return true;
9422    }
9423
9424    public Bundle getAssistContextExtras(int requestType) {
9425        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9426                "getAssistContextExtras()");
9427        PendingAssistExtras pae;
9428        Bundle extras = new Bundle();
9429        synchronized (this) {
9430            ActivityRecord activity = getFocusedStack().mResumedActivity;
9431            if (activity == null) {
9432                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9433                return null;
9434            }
9435            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9436            if (activity.app == null || activity.app.thread == null) {
9437                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9438                return extras;
9439            }
9440            if (activity.app.pid == Binder.getCallingPid()) {
9441                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9442                return extras;
9443            }
9444            pae = new PendingAssistExtras(activity);
9445            try {
9446                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9447                        requestType);
9448                mPendingAssistExtras.add(pae);
9449                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9450            } catch (RemoteException e) {
9451                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9452                return extras;
9453            }
9454        }
9455        synchronized (pae) {
9456            while (!pae.haveResult) {
9457                try {
9458                    pae.wait();
9459                } catch (InterruptedException e) {
9460                }
9461            }
9462            if (pae.result != null) {
9463                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9464            }
9465        }
9466        synchronized (this) {
9467            mPendingAssistExtras.remove(pae);
9468            mHandler.removeCallbacks(pae);
9469        }
9470        return extras;
9471    }
9472
9473    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9474        PendingAssistExtras pae = (PendingAssistExtras)token;
9475        synchronized (pae) {
9476            pae.result = extras;
9477            pae.haveResult = true;
9478            pae.notifyAll();
9479        }
9480    }
9481
9482    public void registerProcessObserver(IProcessObserver observer) {
9483        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9484                "registerProcessObserver()");
9485        synchronized (this) {
9486            mProcessObservers.register(observer);
9487        }
9488    }
9489
9490    @Override
9491    public void unregisterProcessObserver(IProcessObserver observer) {
9492        synchronized (this) {
9493            mProcessObservers.unregister(observer);
9494        }
9495    }
9496
9497    @Override
9498    public boolean convertFromTranslucent(IBinder token) {
9499        final long origId = Binder.clearCallingIdentity();
9500        try {
9501            synchronized (this) {
9502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9503                if (r == null) {
9504                    return false;
9505                }
9506                if (r.changeWindowTranslucency(true)) {
9507                    mWindowManager.setAppFullscreen(token, true);
9508                    r.task.stack.releaseMediaResources();
9509                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9510                    return true;
9511                }
9512                return false;
9513            }
9514        } finally {
9515            Binder.restoreCallingIdentity(origId);
9516        }
9517    }
9518
9519    @Override
9520    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9521        final long origId = Binder.clearCallingIdentity();
9522        try {
9523            synchronized (this) {
9524                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9525                if (r == null) {
9526                    return false;
9527                }
9528                if (r.changeWindowTranslucency(false)) {
9529                    r.task.stack.convertToTranslucent(r, options);
9530                    mWindowManager.setAppFullscreen(token, false);
9531                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9532                    return true;
9533                } else {
9534                    r.task.stack.mReturningActivityOptions = options;
9535                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9536                    return false;
9537                }
9538            }
9539        } finally {
9540            Binder.restoreCallingIdentity(origId);
9541        }
9542    }
9543
9544    @Override
9545    public boolean setMediaPlaying(IBinder token, boolean playing) {
9546        final long origId = Binder.clearCallingIdentity();
9547        try {
9548            synchronized (this) {
9549                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9550                if (r != null) {
9551                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9552                }
9553            }
9554            return false;
9555        } finally {
9556            Binder.restoreCallingIdentity(origId);
9557        }
9558    }
9559
9560    @Override
9561    public boolean isBackgroundMediaPlaying(IBinder token) {
9562        final long origId = Binder.clearCallingIdentity();
9563        try {
9564            synchronized (this) {
9565                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9566                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9567                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9568                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9569                return playing;
9570            }
9571        } finally {
9572            Binder.restoreCallingIdentity(origId);
9573        }
9574    }
9575
9576    @Override
9577    public ActivityOptions getActivityOptions(IBinder token) {
9578        final long origId = Binder.clearCallingIdentity();
9579        try {
9580            synchronized (this) {
9581                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9582                if (r != null) {
9583                    final ActivityOptions activityOptions = r.pendingOptions;
9584                    r.pendingOptions = null;
9585                    return activityOptions;
9586                }
9587                return null;
9588            }
9589        } finally {
9590            Binder.restoreCallingIdentity(origId);
9591        }
9592    }
9593
9594    @Override
9595    public void setImmersive(IBinder token, boolean immersive) {
9596        synchronized(this) {
9597            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9598            if (r == null) {
9599                throw new IllegalArgumentException();
9600            }
9601            r.immersive = immersive;
9602
9603            // update associated state if we're frontmost
9604            if (r == mFocusedActivity) {
9605                if (DEBUG_IMMERSIVE) {
9606                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9607                }
9608                applyUpdateLockStateLocked(r);
9609            }
9610        }
9611    }
9612
9613    @Override
9614    public boolean isImmersive(IBinder token) {
9615        synchronized (this) {
9616            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9617            if (r == null) {
9618                throw new IllegalArgumentException();
9619            }
9620            return r.immersive;
9621        }
9622    }
9623
9624    public boolean isTopActivityImmersive() {
9625        enforceNotIsolatedCaller("startActivity");
9626        synchronized (this) {
9627            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9628            return (r != null) ? r.immersive : false;
9629        }
9630    }
9631
9632    @Override
9633    public boolean isTopOfTask(IBinder token) {
9634        synchronized (this) {
9635            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9636            if (r == null) {
9637                throw new IllegalArgumentException();
9638            }
9639            return r.task.getTopActivity() == r;
9640        }
9641    }
9642
9643    public final void enterSafeMode() {
9644        synchronized(this) {
9645            // It only makes sense to do this before the system is ready
9646            // and started launching other packages.
9647            if (!mSystemReady) {
9648                try {
9649                    AppGlobals.getPackageManager().enterSafeMode();
9650                } catch (RemoteException e) {
9651                }
9652            }
9653
9654            mSafeMode = true;
9655        }
9656    }
9657
9658    public final void showSafeModeOverlay() {
9659        View v = LayoutInflater.from(mContext).inflate(
9660                com.android.internal.R.layout.safe_mode, null);
9661        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9662        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9663        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9664        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9665        lp.gravity = Gravity.BOTTOM | Gravity.START;
9666        lp.format = v.getBackground().getOpacity();
9667        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9668                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9669        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9670        ((WindowManager)mContext.getSystemService(
9671                Context.WINDOW_SERVICE)).addView(v, lp);
9672    }
9673
9674    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9675        if (!(sender instanceof PendingIntentRecord)) {
9676            return;
9677        }
9678        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9679        synchronized (stats) {
9680            if (mBatteryStatsService.isOnBattery()) {
9681                mBatteryStatsService.enforceCallingPermission();
9682                PendingIntentRecord rec = (PendingIntentRecord)sender;
9683                int MY_UID = Binder.getCallingUid();
9684                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9685                BatteryStatsImpl.Uid.Pkg pkg =
9686                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9687                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9688                pkg.incWakeupsLocked();
9689            }
9690        }
9691    }
9692
9693    public boolean killPids(int[] pids, String pReason, boolean secure) {
9694        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9695            throw new SecurityException("killPids only available to the system");
9696        }
9697        String reason = (pReason == null) ? "Unknown" : pReason;
9698        // XXX Note: don't acquire main activity lock here, because the window
9699        // manager calls in with its locks held.
9700
9701        boolean killed = false;
9702        synchronized (mPidsSelfLocked) {
9703            int[] types = new int[pids.length];
9704            int worstType = 0;
9705            for (int i=0; i<pids.length; i++) {
9706                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9707                if (proc != null) {
9708                    int type = proc.setAdj;
9709                    types[i] = type;
9710                    if (type > worstType) {
9711                        worstType = type;
9712                    }
9713                }
9714            }
9715
9716            // If the worst oom_adj is somewhere in the cached proc LRU range,
9717            // then constrain it so we will kill all cached procs.
9718            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9719                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9720                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9721            }
9722
9723            // If this is not a secure call, don't let it kill processes that
9724            // are important.
9725            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9726                worstType = ProcessList.SERVICE_ADJ;
9727            }
9728
9729            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9730            for (int i=0; i<pids.length; i++) {
9731                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9732                if (proc == null) {
9733                    continue;
9734                }
9735                int adj = proc.setAdj;
9736                if (adj >= worstType && !proc.killedByAm) {
9737                    killUnneededProcessLocked(proc, reason);
9738                    killed = true;
9739                }
9740            }
9741        }
9742        return killed;
9743    }
9744
9745    @Override
9746    public void killUid(int uid, String reason) {
9747        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9748            throw new SecurityException("killUid only available to the system");
9749        }
9750        synchronized (this) {
9751            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9752                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9753                    reason != null ? reason : "kill uid");
9754        }
9755    }
9756
9757    @Override
9758    public boolean killProcessesBelowForeground(String reason) {
9759        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9760            throw new SecurityException("killProcessesBelowForeground() only available to system");
9761        }
9762
9763        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9764    }
9765
9766    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9767        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9768            throw new SecurityException("killProcessesBelowAdj() only available to system");
9769        }
9770
9771        boolean killed = false;
9772        synchronized (mPidsSelfLocked) {
9773            final int size = mPidsSelfLocked.size();
9774            for (int i = 0; i < size; i++) {
9775                final int pid = mPidsSelfLocked.keyAt(i);
9776                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9777                if (proc == null) continue;
9778
9779                final int adj = proc.setAdj;
9780                if (adj > belowAdj && !proc.killedByAm) {
9781                    killUnneededProcessLocked(proc, reason);
9782                    killed = true;
9783                }
9784            }
9785        }
9786        return killed;
9787    }
9788
9789    @Override
9790    public void hang(final IBinder who, boolean allowRestart) {
9791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9792                != PackageManager.PERMISSION_GRANTED) {
9793            throw new SecurityException("Requires permission "
9794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9795        }
9796
9797        final IBinder.DeathRecipient death = new DeathRecipient() {
9798            @Override
9799            public void binderDied() {
9800                synchronized (this) {
9801                    notifyAll();
9802                }
9803            }
9804        };
9805
9806        try {
9807            who.linkToDeath(death, 0);
9808        } catch (RemoteException e) {
9809            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9810            return;
9811        }
9812
9813        synchronized (this) {
9814            Watchdog.getInstance().setAllowRestart(allowRestart);
9815            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9816            synchronized (death) {
9817                while (who.isBinderAlive()) {
9818                    try {
9819                        death.wait();
9820                    } catch (InterruptedException e) {
9821                    }
9822                }
9823            }
9824            Watchdog.getInstance().setAllowRestart(true);
9825        }
9826    }
9827
9828    @Override
9829    public void restart() {
9830        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9831                != PackageManager.PERMISSION_GRANTED) {
9832            throw new SecurityException("Requires permission "
9833                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9834        }
9835
9836        Log.i(TAG, "Sending shutdown broadcast...");
9837
9838        BroadcastReceiver br = new BroadcastReceiver() {
9839            @Override public void onReceive(Context context, Intent intent) {
9840                // Now the broadcast is done, finish up the low-level shutdown.
9841                Log.i(TAG, "Shutting down activity manager...");
9842                shutdown(10000);
9843                Log.i(TAG, "Shutdown complete, restarting!");
9844                Process.killProcess(Process.myPid());
9845                System.exit(10);
9846            }
9847        };
9848
9849        // First send the high-level shut down broadcast.
9850        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9851        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9852        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9853        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9854        mContext.sendOrderedBroadcastAsUser(intent,
9855                UserHandle.ALL, null, br, mHandler, 0, null, null);
9856        */
9857        br.onReceive(mContext, intent);
9858    }
9859
9860    private long getLowRamTimeSinceIdle(long now) {
9861        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9862    }
9863
9864    @Override
9865    public void performIdleMaintenance() {
9866        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9867                != PackageManager.PERMISSION_GRANTED) {
9868            throw new SecurityException("Requires permission "
9869                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9870        }
9871
9872        synchronized (this) {
9873            final long now = SystemClock.uptimeMillis();
9874            final long timeSinceLastIdle = now - mLastIdleTime;
9875            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9876            mLastIdleTime = now;
9877            mLowRamTimeSinceLastIdle = 0;
9878            if (mLowRamStartTime != 0) {
9879                mLowRamStartTime = now;
9880            }
9881
9882            StringBuilder sb = new StringBuilder(128);
9883            sb.append("Idle maintenance over ");
9884            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9885            sb.append(" low RAM for ");
9886            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9887            Slog.i(TAG, sb.toString());
9888
9889            // If at least 1/3 of our time since the last idle period has been spent
9890            // with RAM low, then we want to kill processes.
9891            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9892
9893            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9894                ProcessRecord proc = mLruProcesses.get(i);
9895                if (proc.notCachedSinceIdle) {
9896                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9897                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9898                        if (doKilling && proc.initialIdlePss != 0
9899                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9900                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9901                                    + " from " + proc.initialIdlePss + ")");
9902                        }
9903                    }
9904                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9905                    proc.notCachedSinceIdle = true;
9906                    proc.initialIdlePss = 0;
9907                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9908                            isSleeping(), now);
9909                }
9910            }
9911
9912            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9913            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9914        }
9915    }
9916
9917    private void retrieveSettings() {
9918        final ContentResolver resolver = mContext.getContentResolver();
9919        String debugApp = Settings.Global.getString(
9920            resolver, Settings.Global.DEBUG_APP);
9921        boolean waitForDebugger = Settings.Global.getInt(
9922            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9923        boolean alwaysFinishActivities = Settings.Global.getInt(
9924            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9925        boolean forceRtl = Settings.Global.getInt(
9926                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9927        // Transfer any global setting for forcing RTL layout, into a System Property
9928        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9929
9930        Configuration configuration = new Configuration();
9931        Settings.System.getConfiguration(resolver, configuration);
9932        if (forceRtl) {
9933            // This will take care of setting the correct layout direction flags
9934            configuration.setLayoutDirection(configuration.locale);
9935        }
9936
9937        synchronized (this) {
9938            mDebugApp = mOrigDebugApp = debugApp;
9939            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9940            mAlwaysFinishActivities = alwaysFinishActivities;
9941            // This happens before any activities are started, so we can
9942            // change mConfiguration in-place.
9943            updateConfigurationLocked(configuration, null, false, true);
9944            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9945        }
9946    }
9947
9948    public boolean testIsSystemReady() {
9949        // no need to synchronize(this) just to read & return the value
9950        return mSystemReady;
9951    }
9952
9953    private static File getCalledPreBootReceiversFile() {
9954        File dataDir = Environment.getDataDirectory();
9955        File systemDir = new File(dataDir, "system");
9956        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9957        return fname;
9958    }
9959
9960    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9961        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9962        File file = getCalledPreBootReceiversFile();
9963        FileInputStream fis = null;
9964        try {
9965            fis = new FileInputStream(file);
9966            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9967            int fvers = dis.readInt();
9968            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
9969                String vers = dis.readUTF();
9970                String codename = dis.readUTF();
9971                String build = dis.readUTF();
9972                if (android.os.Build.VERSION.RELEASE.equals(vers)
9973                        && android.os.Build.VERSION.CODENAME.equals(codename)
9974                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9975                    int num = dis.readInt();
9976                    while (num > 0) {
9977                        num--;
9978                        String pkg = dis.readUTF();
9979                        String cls = dis.readUTF();
9980                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9981                    }
9982                }
9983            }
9984        } catch (FileNotFoundException e) {
9985        } catch (IOException e) {
9986            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9987        } finally {
9988            if (fis != null) {
9989                try {
9990                    fis.close();
9991                } catch (IOException e) {
9992                }
9993            }
9994        }
9995        return lastDoneReceivers;
9996    }
9997
9998    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9999        File file = getCalledPreBootReceiversFile();
10000        FileOutputStream fos = null;
10001        DataOutputStream dos = null;
10002        try {
10003            fos = new FileOutputStream(file);
10004            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10005            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10006            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10007            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10008            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10009            dos.writeInt(list.size());
10010            for (int i=0; i<list.size(); i++) {
10011                dos.writeUTF(list.get(i).getPackageName());
10012                dos.writeUTF(list.get(i).getClassName());
10013            }
10014        } catch (IOException e) {
10015            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10016            file.delete();
10017        } finally {
10018            FileUtils.sync(fos);
10019            if (dos != null) {
10020                try {
10021                    dos.close();
10022                } catch (IOException e) {
10023                    // TODO Auto-generated catch block
10024                    e.printStackTrace();
10025                }
10026            }
10027        }
10028    }
10029
10030    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10031            ArrayList<ComponentName> doneReceivers, int userId) {
10032        boolean waitingUpdate = false;
10033        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10034        List<ResolveInfo> ris = null;
10035        try {
10036            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10037                    intent, null, 0, userId);
10038        } catch (RemoteException e) {
10039        }
10040        if (ris != null) {
10041            for (int i=ris.size()-1; i>=0; i--) {
10042                if ((ris.get(i).activityInfo.applicationInfo.flags
10043                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10044                    ris.remove(i);
10045                }
10046            }
10047            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10048
10049            // For User 0, load the version number. When delivering to a new user, deliver
10050            // to all receivers.
10051            if (userId == UserHandle.USER_OWNER) {
10052                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10053                for (int i=0; i<ris.size(); i++) {
10054                    ActivityInfo ai = ris.get(i).activityInfo;
10055                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10056                    if (lastDoneReceivers.contains(comp)) {
10057                        // We already did the pre boot receiver for this app with the current
10058                        // platform version, so don't do it again...
10059                        ris.remove(i);
10060                        i--;
10061                        // ...however, do keep it as one that has been done, so we don't
10062                        // forget about it when rewriting the file of last done receivers.
10063                        doneReceivers.add(comp);
10064                    }
10065                }
10066            }
10067
10068            // If primary user, send broadcast to all available users, else just to userId
10069            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10070                    : new int[] { userId };
10071            for (int i = 0; i < ris.size(); i++) {
10072                ActivityInfo ai = ris.get(i).activityInfo;
10073                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10074                doneReceivers.add(comp);
10075                intent.setComponent(comp);
10076                for (int j=0; j<users.length; j++) {
10077                    IIntentReceiver finisher = null;
10078                    // On last receiver and user, set up a completion callback
10079                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10080                        finisher = new IIntentReceiver.Stub() {
10081                            public void performReceive(Intent intent, int resultCode,
10082                                    String data, Bundle extras, boolean ordered,
10083                                    boolean sticky, int sendingUser) {
10084                                // The raw IIntentReceiver interface is called
10085                                // with the AM lock held, so redispatch to
10086                                // execute our code without the lock.
10087                                mHandler.post(onFinishCallback);
10088                            }
10089                        };
10090                    }
10091                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10092                            + " for user " + users[j]);
10093                    broadcastIntentLocked(null, null, intent, null, finisher,
10094                            0, null, null, null, AppOpsManager.OP_NONE,
10095                            true, false, MY_PID, Process.SYSTEM_UID,
10096                            users[j]);
10097                    if (finisher != null) {
10098                        waitingUpdate = true;
10099                    }
10100                }
10101            }
10102        }
10103
10104        return waitingUpdate;
10105    }
10106
10107    public void systemReady(final Runnable goingCallback) {
10108        synchronized(this) {
10109            if (mSystemReady) {
10110                // If we're done calling all the receivers, run the next "boot phase" passed in
10111                // by the SystemServer
10112                if (goingCallback != null) {
10113                    goingCallback.run();
10114                }
10115                return;
10116            }
10117
10118            // Make sure we have the current profile info, since it is needed for
10119            // security checks.
10120            updateCurrentProfileIdsLocked();
10121
10122            if (mRecentTasks == null) {
10123                mRecentTasks = mTaskPersister.restoreTasksLocked();
10124                if (!mRecentTasks.isEmpty()) {
10125                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10126                }
10127                mTaskPersister.startPersisting();
10128            }
10129
10130            // Check to see if there are any update receivers to run.
10131            if (!mDidUpdate) {
10132                if (mWaitingUpdate) {
10133                    return;
10134                }
10135                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10136                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10137                    public void run() {
10138                        synchronized (ActivityManagerService.this) {
10139                            mDidUpdate = true;
10140                        }
10141                        writeLastDonePreBootReceivers(doneReceivers);
10142                        showBootMessage(mContext.getText(
10143                                R.string.android_upgrading_complete),
10144                                false);
10145                        systemReady(goingCallback);
10146                    }
10147                }, doneReceivers, UserHandle.USER_OWNER);
10148
10149                if (mWaitingUpdate) {
10150                    return;
10151                }
10152                mDidUpdate = true;
10153            }
10154
10155            mAppOpsService.systemReady();
10156            mSystemReady = true;
10157        }
10158
10159        ArrayList<ProcessRecord> procsToKill = null;
10160        synchronized(mPidsSelfLocked) {
10161            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10162                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10163                if (!isAllowedWhileBooting(proc.info)){
10164                    if (procsToKill == null) {
10165                        procsToKill = new ArrayList<ProcessRecord>();
10166                    }
10167                    procsToKill.add(proc);
10168                }
10169            }
10170        }
10171
10172        synchronized(this) {
10173            if (procsToKill != null) {
10174                for (int i=procsToKill.size()-1; i>=0; i--) {
10175                    ProcessRecord proc = procsToKill.get(i);
10176                    Slog.i(TAG, "Removing system update proc: " + proc);
10177                    removeProcessLocked(proc, true, false, "system update done");
10178                }
10179            }
10180
10181            // Now that we have cleaned up any update processes, we
10182            // are ready to start launching real processes and know that
10183            // we won't trample on them any more.
10184            mProcessesReady = true;
10185        }
10186
10187        Slog.i(TAG, "System now ready");
10188        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10189            SystemClock.uptimeMillis());
10190
10191        synchronized(this) {
10192            // Make sure we have no pre-ready processes sitting around.
10193
10194            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10195                ResolveInfo ri = mContext.getPackageManager()
10196                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10197                                STOCK_PM_FLAGS);
10198                CharSequence errorMsg = null;
10199                if (ri != null) {
10200                    ActivityInfo ai = ri.activityInfo;
10201                    ApplicationInfo app = ai.applicationInfo;
10202                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10203                        mTopAction = Intent.ACTION_FACTORY_TEST;
10204                        mTopData = null;
10205                        mTopComponent = new ComponentName(app.packageName,
10206                                ai.name);
10207                    } else {
10208                        errorMsg = mContext.getResources().getText(
10209                                com.android.internal.R.string.factorytest_not_system);
10210                    }
10211                } else {
10212                    errorMsg = mContext.getResources().getText(
10213                            com.android.internal.R.string.factorytest_no_action);
10214                }
10215                if (errorMsg != null) {
10216                    mTopAction = null;
10217                    mTopData = null;
10218                    mTopComponent = null;
10219                    Message msg = Message.obtain();
10220                    msg.what = SHOW_FACTORY_ERROR_MSG;
10221                    msg.getData().putCharSequence("msg", errorMsg);
10222                    mHandler.sendMessage(msg);
10223                }
10224            }
10225        }
10226
10227        retrieveSettings();
10228
10229        synchronized (this) {
10230            readGrantedUriPermissionsLocked();
10231        }
10232
10233        if (goingCallback != null) goingCallback.run();
10234
10235        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10236                Integer.toString(mCurrentUserId), mCurrentUserId);
10237        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10238                Integer.toString(mCurrentUserId), mCurrentUserId);
10239        mSystemServiceManager.startUser(mCurrentUserId);
10240
10241        synchronized (this) {
10242            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10243                try {
10244                    List apps = AppGlobals.getPackageManager().
10245                        getPersistentApplications(STOCK_PM_FLAGS);
10246                    if (apps != null) {
10247                        int N = apps.size();
10248                        int i;
10249                        for (i=0; i<N; i++) {
10250                            ApplicationInfo info
10251                                = (ApplicationInfo)apps.get(i);
10252                            if (info != null &&
10253                                    !info.packageName.equals("android")) {
10254                                addAppLocked(info, false, null /* ABI override */);
10255                            }
10256                        }
10257                    }
10258                } catch (RemoteException ex) {
10259                    // pm is in same process, this will never happen.
10260                }
10261            }
10262
10263            // Start up initial activity.
10264            mBooting = true;
10265
10266            try {
10267                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10268                    Message msg = Message.obtain();
10269                    msg.what = SHOW_UID_ERROR_MSG;
10270                    mHandler.sendMessage(msg);
10271                }
10272            } catch (RemoteException e) {
10273            }
10274
10275            long ident = Binder.clearCallingIdentity();
10276            try {
10277                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10278                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10279                        | Intent.FLAG_RECEIVER_FOREGROUND);
10280                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10281                broadcastIntentLocked(null, null, intent,
10282                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10283                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10284                intent = new Intent(Intent.ACTION_USER_STARTING);
10285                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10286                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10287                broadcastIntentLocked(null, null, intent,
10288                        null, new IIntentReceiver.Stub() {
10289                            @Override
10290                            public void performReceive(Intent intent, int resultCode, String data,
10291                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10292                                    throws RemoteException {
10293                            }
10294                        }, 0, null, null,
10295                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10296                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10297            } catch (Throwable t) {
10298                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10299            } finally {
10300                Binder.restoreCallingIdentity(ident);
10301            }
10302            mStackSupervisor.resumeTopActivitiesLocked();
10303            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10304        }
10305    }
10306
10307    private boolean makeAppCrashingLocked(ProcessRecord app,
10308            String shortMsg, String longMsg, String stackTrace) {
10309        app.crashing = true;
10310        app.crashingReport = generateProcessError(app,
10311                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10312        startAppProblemLocked(app);
10313        app.stopFreezingAllLocked();
10314        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10315    }
10316
10317    private void makeAppNotRespondingLocked(ProcessRecord app,
10318            String activity, String shortMsg, String longMsg) {
10319        app.notResponding = true;
10320        app.notRespondingReport = generateProcessError(app,
10321                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10322                activity, shortMsg, longMsg, null);
10323        startAppProblemLocked(app);
10324        app.stopFreezingAllLocked();
10325    }
10326
10327    /**
10328     * Generate a process error record, suitable for attachment to a ProcessRecord.
10329     *
10330     * @param app The ProcessRecord in which the error occurred.
10331     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10332     *                      ActivityManager.AppErrorStateInfo
10333     * @param activity The activity associated with the crash, if known.
10334     * @param shortMsg Short message describing the crash.
10335     * @param longMsg Long message describing the crash.
10336     * @param stackTrace Full crash stack trace, may be null.
10337     *
10338     * @return Returns a fully-formed AppErrorStateInfo record.
10339     */
10340    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10341            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10342        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10343
10344        report.condition = condition;
10345        report.processName = app.processName;
10346        report.pid = app.pid;
10347        report.uid = app.info.uid;
10348        report.tag = activity;
10349        report.shortMsg = shortMsg;
10350        report.longMsg = longMsg;
10351        report.stackTrace = stackTrace;
10352
10353        return report;
10354    }
10355
10356    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10357        synchronized (this) {
10358            app.crashing = false;
10359            app.crashingReport = null;
10360            app.notResponding = false;
10361            app.notRespondingReport = null;
10362            if (app.anrDialog == fromDialog) {
10363                app.anrDialog = null;
10364            }
10365            if (app.waitDialog == fromDialog) {
10366                app.waitDialog = null;
10367            }
10368            if (app.pid > 0 && app.pid != MY_PID) {
10369                handleAppCrashLocked(app, null, null, null);
10370                killUnneededProcessLocked(app, "user request after error");
10371            }
10372        }
10373    }
10374
10375    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10376            String stackTrace) {
10377        long now = SystemClock.uptimeMillis();
10378
10379        Long crashTime;
10380        if (!app.isolated) {
10381            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10382        } else {
10383            crashTime = null;
10384        }
10385        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10386            // This process loses!
10387            Slog.w(TAG, "Process " + app.info.processName
10388                    + " has crashed too many times: killing!");
10389            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10390                    app.userId, app.info.processName, app.uid);
10391            mStackSupervisor.handleAppCrashLocked(app);
10392            if (!app.persistent) {
10393                // We don't want to start this process again until the user
10394                // explicitly does so...  but for persistent process, we really
10395                // need to keep it running.  If a persistent process is actually
10396                // repeatedly crashing, then badness for everyone.
10397                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10398                        app.info.processName);
10399                if (!app.isolated) {
10400                    // XXX We don't have a way to mark isolated processes
10401                    // as bad, since they don't have a peristent identity.
10402                    mBadProcesses.put(app.info.processName, app.uid,
10403                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10404                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10405                }
10406                app.bad = true;
10407                app.removed = true;
10408                // Don't let services in this process be restarted and potentially
10409                // annoy the user repeatedly.  Unless it is persistent, since those
10410                // processes run critical code.
10411                removeProcessLocked(app, false, false, "crash");
10412                mStackSupervisor.resumeTopActivitiesLocked();
10413                return false;
10414            }
10415            mStackSupervisor.resumeTopActivitiesLocked();
10416        } else {
10417            mStackSupervisor.finishTopRunningActivityLocked(app);
10418        }
10419
10420        // Bump up the crash count of any services currently running in the proc.
10421        for (int i=app.services.size()-1; i>=0; i--) {
10422            // Any services running in the application need to be placed
10423            // back in the pending list.
10424            ServiceRecord sr = app.services.valueAt(i);
10425            sr.crashCount++;
10426        }
10427
10428        // If the crashing process is what we consider to be the "home process" and it has been
10429        // replaced by a third-party app, clear the package preferred activities from packages
10430        // with a home activity running in the process to prevent a repeatedly crashing app
10431        // from blocking the user to manually clear the list.
10432        final ArrayList<ActivityRecord> activities = app.activities;
10433        if (app == mHomeProcess && activities.size() > 0
10434                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10435            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10436                final ActivityRecord r = activities.get(activityNdx);
10437                if (r.isHomeActivity()) {
10438                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10439                    try {
10440                        ActivityThread.getPackageManager()
10441                                .clearPackagePreferredActivities(r.packageName);
10442                    } catch (RemoteException c) {
10443                        // pm is in same process, this will never happen.
10444                    }
10445                }
10446            }
10447        }
10448
10449        if (!app.isolated) {
10450            // XXX Can't keep track of crash times for isolated processes,
10451            // because they don't have a perisistent identity.
10452            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10453        }
10454
10455        return true;
10456    }
10457
10458    void startAppProblemLocked(ProcessRecord app) {
10459        if (app.userId == mCurrentUserId) {
10460            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10461                    mContext, app.info.packageName, app.info.flags);
10462        } else {
10463            // If this app is not running under the current user, then we
10464            // can't give it a report button because that would require
10465            // launching the report UI under a different user.
10466            app.errorReportReceiver = null;
10467        }
10468        skipCurrentReceiverLocked(app);
10469    }
10470
10471    void skipCurrentReceiverLocked(ProcessRecord app) {
10472        for (BroadcastQueue queue : mBroadcastQueues) {
10473            queue.skipCurrentReceiverLocked(app);
10474        }
10475    }
10476
10477    /**
10478     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10479     * The application process will exit immediately after this call returns.
10480     * @param app object of the crashing app, null for the system server
10481     * @param crashInfo describing the exception
10482     */
10483    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10484        ProcessRecord r = findAppProcess(app, "Crash");
10485        final String processName = app == null ? "system_server"
10486                : (r == null ? "unknown" : r.processName);
10487
10488        handleApplicationCrashInner("crash", r, processName, crashInfo);
10489    }
10490
10491    /* Native crash reporting uses this inner version because it needs to be somewhat
10492     * decoupled from the AM-managed cleanup lifecycle
10493     */
10494    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10495            ApplicationErrorReport.CrashInfo crashInfo) {
10496        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10497                UserHandle.getUserId(Binder.getCallingUid()), processName,
10498                r == null ? -1 : r.info.flags,
10499                crashInfo.exceptionClassName,
10500                crashInfo.exceptionMessage,
10501                crashInfo.throwFileName,
10502                crashInfo.throwLineNumber);
10503
10504        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10505
10506        crashApplication(r, crashInfo);
10507    }
10508
10509    public void handleApplicationStrictModeViolation(
10510            IBinder app,
10511            int violationMask,
10512            StrictMode.ViolationInfo info) {
10513        ProcessRecord r = findAppProcess(app, "StrictMode");
10514        if (r == null) {
10515            return;
10516        }
10517
10518        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10519            Integer stackFingerprint = info.hashCode();
10520            boolean logIt = true;
10521            synchronized (mAlreadyLoggedViolatedStacks) {
10522                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10523                    logIt = false;
10524                    // TODO: sub-sample into EventLog for these, with
10525                    // the info.durationMillis?  Then we'd get
10526                    // the relative pain numbers, without logging all
10527                    // the stack traces repeatedly.  We'd want to do
10528                    // likewise in the client code, which also does
10529                    // dup suppression, before the Binder call.
10530                } else {
10531                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10532                        mAlreadyLoggedViolatedStacks.clear();
10533                    }
10534                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10535                }
10536            }
10537            if (logIt) {
10538                logStrictModeViolationToDropBox(r, info);
10539            }
10540        }
10541
10542        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10543            AppErrorResult result = new AppErrorResult();
10544            synchronized (this) {
10545                final long origId = Binder.clearCallingIdentity();
10546
10547                Message msg = Message.obtain();
10548                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10549                HashMap<String, Object> data = new HashMap<String, Object>();
10550                data.put("result", result);
10551                data.put("app", r);
10552                data.put("violationMask", violationMask);
10553                data.put("info", info);
10554                msg.obj = data;
10555                mHandler.sendMessage(msg);
10556
10557                Binder.restoreCallingIdentity(origId);
10558            }
10559            int res = result.get();
10560            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10561        }
10562    }
10563
10564    // Depending on the policy in effect, there could be a bunch of
10565    // these in quick succession so we try to batch these together to
10566    // minimize disk writes, number of dropbox entries, and maximize
10567    // compression, by having more fewer, larger records.
10568    private void logStrictModeViolationToDropBox(
10569            ProcessRecord process,
10570            StrictMode.ViolationInfo info) {
10571        if (info == null) {
10572            return;
10573        }
10574        final boolean isSystemApp = process == null ||
10575                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10576                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10577        final String processName = process == null ? "unknown" : process.processName;
10578        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10579        final DropBoxManager dbox = (DropBoxManager)
10580                mContext.getSystemService(Context.DROPBOX_SERVICE);
10581
10582        // Exit early if the dropbox isn't configured to accept this report type.
10583        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10584
10585        boolean bufferWasEmpty;
10586        boolean needsFlush;
10587        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10588        synchronized (sb) {
10589            bufferWasEmpty = sb.length() == 0;
10590            appendDropBoxProcessHeaders(process, processName, sb);
10591            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10592            sb.append("System-App: ").append(isSystemApp).append("\n");
10593            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10594            if (info.violationNumThisLoop != 0) {
10595                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10596            }
10597            if (info.numAnimationsRunning != 0) {
10598                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10599            }
10600            if (info.broadcastIntentAction != null) {
10601                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10602            }
10603            if (info.durationMillis != -1) {
10604                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10605            }
10606            if (info.numInstances != -1) {
10607                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10608            }
10609            if (info.tags != null) {
10610                for (String tag : info.tags) {
10611                    sb.append("Span-Tag: ").append(tag).append("\n");
10612                }
10613            }
10614            sb.append("\n");
10615            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10616                sb.append(info.crashInfo.stackTrace);
10617            }
10618            sb.append("\n");
10619
10620            // Only buffer up to ~64k.  Various logging bits truncate
10621            // things at 128k.
10622            needsFlush = (sb.length() > 64 * 1024);
10623        }
10624
10625        // Flush immediately if the buffer's grown too large, or this
10626        // is a non-system app.  Non-system apps are isolated with a
10627        // different tag & policy and not batched.
10628        //
10629        // Batching is useful during internal testing with
10630        // StrictMode settings turned up high.  Without batching,
10631        // thousands of separate files could be created on boot.
10632        if (!isSystemApp || needsFlush) {
10633            new Thread("Error dump: " + dropboxTag) {
10634                @Override
10635                public void run() {
10636                    String report;
10637                    synchronized (sb) {
10638                        report = sb.toString();
10639                        sb.delete(0, sb.length());
10640                        sb.trimToSize();
10641                    }
10642                    if (report.length() != 0) {
10643                        dbox.addText(dropboxTag, report);
10644                    }
10645                }
10646            }.start();
10647            return;
10648        }
10649
10650        // System app batching:
10651        if (!bufferWasEmpty) {
10652            // An existing dropbox-writing thread is outstanding, so
10653            // we don't need to start it up.  The existing thread will
10654            // catch the buffer appends we just did.
10655            return;
10656        }
10657
10658        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10659        // (After this point, we shouldn't access AMS internal data structures.)
10660        new Thread("Error dump: " + dropboxTag) {
10661            @Override
10662            public void run() {
10663                // 5 second sleep to let stacks arrive and be batched together
10664                try {
10665                    Thread.sleep(5000);  // 5 seconds
10666                } catch (InterruptedException e) {}
10667
10668                String errorReport;
10669                synchronized (mStrictModeBuffer) {
10670                    errorReport = mStrictModeBuffer.toString();
10671                    if (errorReport.length() == 0) {
10672                        return;
10673                    }
10674                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10675                    mStrictModeBuffer.trimToSize();
10676                }
10677                dbox.addText(dropboxTag, errorReport);
10678            }
10679        }.start();
10680    }
10681
10682    /**
10683     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10684     * @param app object of the crashing app, null for the system server
10685     * @param tag reported by the caller
10686     * @param crashInfo describing the context of the error
10687     * @return true if the process should exit immediately (WTF is fatal)
10688     */
10689    public boolean handleApplicationWtf(IBinder app, String tag,
10690            ApplicationErrorReport.CrashInfo crashInfo) {
10691        ProcessRecord r = findAppProcess(app, "WTF");
10692        final String processName = app == null ? "system_server"
10693                : (r == null ? "unknown" : r.processName);
10694
10695        EventLog.writeEvent(EventLogTags.AM_WTF,
10696                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10697                processName,
10698                r == null ? -1 : r.info.flags,
10699                tag, crashInfo.exceptionMessage);
10700
10701        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10702
10703        if (r != null && r.pid != Process.myPid() &&
10704                Settings.Global.getInt(mContext.getContentResolver(),
10705                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10706            crashApplication(r, crashInfo);
10707            return true;
10708        } else {
10709            return false;
10710        }
10711    }
10712
10713    /**
10714     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10715     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10716     */
10717    private ProcessRecord findAppProcess(IBinder app, String reason) {
10718        if (app == null) {
10719            return null;
10720        }
10721
10722        synchronized (this) {
10723            final int NP = mProcessNames.getMap().size();
10724            for (int ip=0; ip<NP; ip++) {
10725                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10726                final int NA = apps.size();
10727                for (int ia=0; ia<NA; ia++) {
10728                    ProcessRecord p = apps.valueAt(ia);
10729                    if (p.thread != null && p.thread.asBinder() == app) {
10730                        return p;
10731                    }
10732                }
10733            }
10734
10735            Slog.w(TAG, "Can't find mystery application for " + reason
10736                    + " from pid=" + Binder.getCallingPid()
10737                    + " uid=" + Binder.getCallingUid() + ": " + app);
10738            return null;
10739        }
10740    }
10741
10742    /**
10743     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10744     * to append various headers to the dropbox log text.
10745     */
10746    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10747            StringBuilder sb) {
10748        // Watchdog thread ends up invoking this function (with
10749        // a null ProcessRecord) to add the stack file to dropbox.
10750        // Do not acquire a lock on this (am) in such cases, as it
10751        // could cause a potential deadlock, if and when watchdog
10752        // is invoked due to unavailability of lock on am and it
10753        // would prevent watchdog from killing system_server.
10754        if (process == null) {
10755            sb.append("Process: ").append(processName).append("\n");
10756            return;
10757        }
10758        // Note: ProcessRecord 'process' is guarded by the service
10759        // instance.  (notably process.pkgList, which could otherwise change
10760        // concurrently during execution of this method)
10761        synchronized (this) {
10762            sb.append("Process: ").append(processName).append("\n");
10763            int flags = process.info.flags;
10764            IPackageManager pm = AppGlobals.getPackageManager();
10765            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10766            for (int ip=0; ip<process.pkgList.size(); ip++) {
10767                String pkg = process.pkgList.keyAt(ip);
10768                sb.append("Package: ").append(pkg);
10769                try {
10770                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10771                    if (pi != null) {
10772                        sb.append(" v").append(pi.versionCode);
10773                        if (pi.versionName != null) {
10774                            sb.append(" (").append(pi.versionName).append(")");
10775                        }
10776                    }
10777                } catch (RemoteException e) {
10778                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10779                }
10780                sb.append("\n");
10781            }
10782        }
10783    }
10784
10785    private static String processClass(ProcessRecord process) {
10786        if (process == null || process.pid == MY_PID) {
10787            return "system_server";
10788        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10789            return "system_app";
10790        } else {
10791            return "data_app";
10792        }
10793    }
10794
10795    /**
10796     * Write a description of an error (crash, WTF, ANR) to the drop box.
10797     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10798     * @param process which caused the error, null means the system server
10799     * @param activity which triggered the error, null if unknown
10800     * @param parent activity related to the error, null if unknown
10801     * @param subject line related to the error, null if absent
10802     * @param report in long form describing the error, null if absent
10803     * @param logFile to include in the report, null if none
10804     * @param crashInfo giving an application stack trace, null if absent
10805     */
10806    public void addErrorToDropBox(String eventType,
10807            ProcessRecord process, String processName, ActivityRecord activity,
10808            ActivityRecord parent, String subject,
10809            final String report, final File logFile,
10810            final ApplicationErrorReport.CrashInfo crashInfo) {
10811        // NOTE -- this must never acquire the ActivityManagerService lock,
10812        // otherwise the watchdog may be prevented from resetting the system.
10813
10814        final String dropboxTag = processClass(process) + "_" + eventType;
10815        final DropBoxManager dbox = (DropBoxManager)
10816                mContext.getSystemService(Context.DROPBOX_SERVICE);
10817
10818        // Exit early if the dropbox isn't configured to accept this report type.
10819        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10820
10821        final StringBuilder sb = new StringBuilder(1024);
10822        appendDropBoxProcessHeaders(process, processName, sb);
10823        if (activity != null) {
10824            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10825        }
10826        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10827            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10828        }
10829        if (parent != null && parent != activity) {
10830            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10831        }
10832        if (subject != null) {
10833            sb.append("Subject: ").append(subject).append("\n");
10834        }
10835        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10836        if (Debug.isDebuggerConnected()) {
10837            sb.append("Debugger: Connected\n");
10838        }
10839        sb.append("\n");
10840
10841        // Do the rest in a worker thread to avoid blocking the caller on I/O
10842        // (After this point, we shouldn't access AMS internal data structures.)
10843        Thread worker = new Thread("Error dump: " + dropboxTag) {
10844            @Override
10845            public void run() {
10846                if (report != null) {
10847                    sb.append(report);
10848                }
10849                if (logFile != null) {
10850                    try {
10851                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10852                                    "\n\n[[TRUNCATED]]"));
10853                    } catch (IOException e) {
10854                        Slog.e(TAG, "Error reading " + logFile, e);
10855                    }
10856                }
10857                if (crashInfo != null && crashInfo.stackTrace != null) {
10858                    sb.append(crashInfo.stackTrace);
10859                }
10860
10861                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10862                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10863                if (lines > 0) {
10864                    sb.append("\n");
10865
10866                    // Merge several logcat streams, and take the last N lines
10867                    InputStreamReader input = null;
10868                    try {
10869                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10870                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10871                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10872
10873                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10874                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10875                        input = new InputStreamReader(logcat.getInputStream());
10876
10877                        int num;
10878                        char[] buf = new char[8192];
10879                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10880                    } catch (IOException e) {
10881                        Slog.e(TAG, "Error running logcat", e);
10882                    } finally {
10883                        if (input != null) try { input.close(); } catch (IOException e) {}
10884                    }
10885                }
10886
10887                dbox.addText(dropboxTag, sb.toString());
10888            }
10889        };
10890
10891        if (process == null) {
10892            // If process is null, we are being called from some internal code
10893            // and may be about to die -- run this synchronously.
10894            worker.run();
10895        } else {
10896            worker.start();
10897        }
10898    }
10899
10900    /**
10901     * Bring up the "unexpected error" dialog box for a crashing app.
10902     * Deal with edge cases (intercepts from instrumented applications,
10903     * ActivityController, error intent receivers, that sort of thing).
10904     * @param r the application crashing
10905     * @param crashInfo describing the failure
10906     */
10907    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10908        long timeMillis = System.currentTimeMillis();
10909        String shortMsg = crashInfo.exceptionClassName;
10910        String longMsg = crashInfo.exceptionMessage;
10911        String stackTrace = crashInfo.stackTrace;
10912        if (shortMsg != null && longMsg != null) {
10913            longMsg = shortMsg + ": " + longMsg;
10914        } else if (shortMsg != null) {
10915            longMsg = shortMsg;
10916        }
10917
10918        AppErrorResult result = new AppErrorResult();
10919        synchronized (this) {
10920            if (mController != null) {
10921                try {
10922                    String name = r != null ? r.processName : null;
10923                    int pid = r != null ? r.pid : Binder.getCallingPid();
10924                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10925                    if (!mController.appCrashed(name, pid,
10926                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10927                        Slog.w(TAG, "Force-killing crashed app " + name
10928                                + " at watcher's request");
10929                        Process.killProcess(pid);
10930                        if (r != null) {
10931                            Process.killProcessGroup(uid, pid);
10932                        }
10933                        return;
10934                    }
10935                } catch (RemoteException e) {
10936                    mController = null;
10937                    Watchdog.getInstance().setActivityController(null);
10938                }
10939            }
10940
10941            final long origId = Binder.clearCallingIdentity();
10942
10943            // If this process is running instrumentation, finish it.
10944            if (r != null && r.instrumentationClass != null) {
10945                Slog.w(TAG, "Error in app " + r.processName
10946                      + " running instrumentation " + r.instrumentationClass + ":");
10947                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10948                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10949                Bundle info = new Bundle();
10950                info.putString("shortMsg", shortMsg);
10951                info.putString("longMsg", longMsg);
10952                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10953                Binder.restoreCallingIdentity(origId);
10954                return;
10955            }
10956
10957            // If we can't identify the process or it's already exceeded its crash quota,
10958            // quit right away without showing a crash dialog.
10959            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10960                Binder.restoreCallingIdentity(origId);
10961                return;
10962            }
10963
10964            Message msg = Message.obtain();
10965            msg.what = SHOW_ERROR_MSG;
10966            HashMap data = new HashMap();
10967            data.put("result", result);
10968            data.put("app", r);
10969            msg.obj = data;
10970            mHandler.sendMessage(msg);
10971
10972            Binder.restoreCallingIdentity(origId);
10973        }
10974
10975        int res = result.get();
10976
10977        Intent appErrorIntent = null;
10978        synchronized (this) {
10979            if (r != null && !r.isolated) {
10980                // XXX Can't keep track of crash time for isolated processes,
10981                // since they don't have a persistent identity.
10982                mProcessCrashTimes.put(r.info.processName, r.uid,
10983                        SystemClock.uptimeMillis());
10984            }
10985            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10986                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10987            }
10988        }
10989
10990        if (appErrorIntent != null) {
10991            try {
10992                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10993            } catch (ActivityNotFoundException e) {
10994                Slog.w(TAG, "bug report receiver dissappeared", e);
10995            }
10996        }
10997    }
10998
10999    Intent createAppErrorIntentLocked(ProcessRecord r,
11000            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11001        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11002        if (report == null) {
11003            return null;
11004        }
11005        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11006        result.setComponent(r.errorReportReceiver);
11007        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11008        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11009        return result;
11010    }
11011
11012    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11013            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11014        if (r.errorReportReceiver == null) {
11015            return null;
11016        }
11017
11018        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11019            return null;
11020        }
11021
11022        ApplicationErrorReport report = new ApplicationErrorReport();
11023        report.packageName = r.info.packageName;
11024        report.installerPackageName = r.errorReportReceiver.getPackageName();
11025        report.processName = r.processName;
11026        report.time = timeMillis;
11027        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11028
11029        if (r.crashing || r.forceCrashReport) {
11030            report.type = ApplicationErrorReport.TYPE_CRASH;
11031            report.crashInfo = crashInfo;
11032        } else if (r.notResponding) {
11033            report.type = ApplicationErrorReport.TYPE_ANR;
11034            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11035
11036            report.anrInfo.activity = r.notRespondingReport.tag;
11037            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11038            report.anrInfo.info = r.notRespondingReport.longMsg;
11039        }
11040
11041        return report;
11042    }
11043
11044    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11045        enforceNotIsolatedCaller("getProcessesInErrorState");
11046        // assume our apps are happy - lazy create the list
11047        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11048
11049        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11050                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11051        int userId = UserHandle.getUserId(Binder.getCallingUid());
11052
11053        synchronized (this) {
11054
11055            // iterate across all processes
11056            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11057                ProcessRecord app = mLruProcesses.get(i);
11058                if (!allUsers && app.userId != userId) {
11059                    continue;
11060                }
11061                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11062                    // This one's in trouble, so we'll generate a report for it
11063                    // crashes are higher priority (in case there's a crash *and* an anr)
11064                    ActivityManager.ProcessErrorStateInfo report = null;
11065                    if (app.crashing) {
11066                        report = app.crashingReport;
11067                    } else if (app.notResponding) {
11068                        report = app.notRespondingReport;
11069                    }
11070
11071                    if (report != null) {
11072                        if (errList == null) {
11073                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11074                        }
11075                        errList.add(report);
11076                    } else {
11077                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11078                                " crashing = " + app.crashing +
11079                                " notResponding = " + app.notResponding);
11080                    }
11081                }
11082            }
11083        }
11084
11085        return errList;
11086    }
11087
11088    static int procStateToImportance(int procState, int memAdj,
11089            ActivityManager.RunningAppProcessInfo currApp) {
11090        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11091        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11092            currApp.lru = memAdj;
11093        } else {
11094            currApp.lru = 0;
11095        }
11096        return imp;
11097    }
11098
11099    private void fillInProcMemInfo(ProcessRecord app,
11100            ActivityManager.RunningAppProcessInfo outInfo) {
11101        outInfo.pid = app.pid;
11102        outInfo.uid = app.info.uid;
11103        if (mHeavyWeightProcess == app) {
11104            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11105        }
11106        if (app.persistent) {
11107            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11108        }
11109        if (app.activities.size() > 0) {
11110            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11111        }
11112        outInfo.lastTrimLevel = app.trimMemoryLevel;
11113        int adj = app.curAdj;
11114        int procState = app.curProcState;
11115        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11116        outInfo.importanceReasonCode = app.adjTypeCode;
11117        outInfo.processState = app.curProcState;
11118    }
11119
11120    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11121        enforceNotIsolatedCaller("getRunningAppProcesses");
11122        // Lazy instantiation of list
11123        List<ActivityManager.RunningAppProcessInfo> runList = null;
11124        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11125                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11126        int userId = UserHandle.getUserId(Binder.getCallingUid());
11127        synchronized (this) {
11128            // Iterate across all processes
11129            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11130                ProcessRecord app = mLruProcesses.get(i);
11131                if (!allUsers && app.userId != userId) {
11132                    continue;
11133                }
11134                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11135                    // Generate process state info for running application
11136                    ActivityManager.RunningAppProcessInfo currApp =
11137                        new ActivityManager.RunningAppProcessInfo(app.processName,
11138                                app.pid, app.getPackageList());
11139                    fillInProcMemInfo(app, currApp);
11140                    if (app.adjSource instanceof ProcessRecord) {
11141                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11142                        currApp.importanceReasonImportance =
11143                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11144                                        app.adjSourceProcState);
11145                    } else if (app.adjSource instanceof ActivityRecord) {
11146                        ActivityRecord r = (ActivityRecord)app.adjSource;
11147                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11148                    }
11149                    if (app.adjTarget instanceof ComponentName) {
11150                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11151                    }
11152                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11153                    //        + " lru=" + currApp.lru);
11154                    if (runList == null) {
11155                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11156                    }
11157                    runList.add(currApp);
11158                }
11159            }
11160        }
11161        return runList;
11162    }
11163
11164    public List<ApplicationInfo> getRunningExternalApplications() {
11165        enforceNotIsolatedCaller("getRunningExternalApplications");
11166        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11167        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11168        if (runningApps != null && runningApps.size() > 0) {
11169            Set<String> extList = new HashSet<String>();
11170            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11171                if (app.pkgList != null) {
11172                    for (String pkg : app.pkgList) {
11173                        extList.add(pkg);
11174                    }
11175                }
11176            }
11177            IPackageManager pm = AppGlobals.getPackageManager();
11178            for (String pkg : extList) {
11179                try {
11180                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11181                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11182                        retList.add(info);
11183                    }
11184                } catch (RemoteException e) {
11185                }
11186            }
11187        }
11188        return retList;
11189    }
11190
11191    @Override
11192    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11193        enforceNotIsolatedCaller("getMyMemoryState");
11194        synchronized (this) {
11195            ProcessRecord proc;
11196            synchronized (mPidsSelfLocked) {
11197                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11198            }
11199            fillInProcMemInfo(proc, outInfo);
11200        }
11201    }
11202
11203    @Override
11204    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11205        if (checkCallingPermission(android.Manifest.permission.DUMP)
11206                != PackageManager.PERMISSION_GRANTED) {
11207            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11208                    + Binder.getCallingPid()
11209                    + ", uid=" + Binder.getCallingUid()
11210                    + " without permission "
11211                    + android.Manifest.permission.DUMP);
11212            return;
11213        }
11214
11215        boolean dumpAll = false;
11216        boolean dumpClient = false;
11217        String dumpPackage = null;
11218
11219        int opti = 0;
11220        while (opti < args.length) {
11221            String opt = args[opti];
11222            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11223                break;
11224            }
11225            opti++;
11226            if ("-a".equals(opt)) {
11227                dumpAll = true;
11228            } else if ("-c".equals(opt)) {
11229                dumpClient = true;
11230            } else if ("-h".equals(opt)) {
11231                pw.println("Activity manager dump options:");
11232                pw.println("  [-a] [-c] [-h] [cmd] ...");
11233                pw.println("  cmd may be one of:");
11234                pw.println("    a[ctivities]: activity stack state");
11235                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11236                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11237                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11238                pw.println("    o[om]: out of memory management");
11239                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11240                pw.println("    provider [COMP_SPEC]: provider client-side state");
11241                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11242                pw.println("    service [COMP_SPEC]: service client-side state");
11243                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11244                pw.println("    all: dump all activities");
11245                pw.println("    top: dump the top activity");
11246                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11247                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11248                pw.println("    a partial substring in a component name, a");
11249                pw.println("    hex object identifier.");
11250                pw.println("  -a: include all available server state.");
11251                pw.println("  -c: include client state.");
11252                return;
11253            } else {
11254                pw.println("Unknown argument: " + opt + "; use -h for help");
11255            }
11256        }
11257
11258        long origId = Binder.clearCallingIdentity();
11259        boolean more = false;
11260        // Is the caller requesting to dump a particular piece of data?
11261        if (opti < args.length) {
11262            String cmd = args[opti];
11263            opti++;
11264            if ("activities".equals(cmd) || "a".equals(cmd)) {
11265                synchronized (this) {
11266                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11267                }
11268            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11269                String[] newArgs;
11270                String name;
11271                if (opti >= args.length) {
11272                    name = null;
11273                    newArgs = EMPTY_STRING_ARRAY;
11274                } else {
11275                    name = args[opti];
11276                    opti++;
11277                    newArgs = new String[args.length - opti];
11278                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11279                            args.length - opti);
11280                }
11281                synchronized (this) {
11282                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11283                }
11284            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11285                String[] newArgs;
11286                String name;
11287                if (opti >= args.length) {
11288                    name = null;
11289                    newArgs = EMPTY_STRING_ARRAY;
11290                } else {
11291                    name = args[opti];
11292                    opti++;
11293                    newArgs = new String[args.length - opti];
11294                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11295                            args.length - opti);
11296                }
11297                synchronized (this) {
11298                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11299                }
11300            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11301                String[] newArgs;
11302                String name;
11303                if (opti >= args.length) {
11304                    name = null;
11305                    newArgs = EMPTY_STRING_ARRAY;
11306                } else {
11307                    name = args[opti];
11308                    opti++;
11309                    newArgs = new String[args.length - opti];
11310                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11311                            args.length - opti);
11312                }
11313                synchronized (this) {
11314                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11315                }
11316            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11317                synchronized (this) {
11318                    dumpOomLocked(fd, pw, args, opti, true);
11319                }
11320            } else if ("provider".equals(cmd)) {
11321                String[] newArgs;
11322                String name;
11323                if (opti >= args.length) {
11324                    name = null;
11325                    newArgs = EMPTY_STRING_ARRAY;
11326                } else {
11327                    name = args[opti];
11328                    opti++;
11329                    newArgs = new String[args.length - opti];
11330                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11331                }
11332                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11333                    pw.println("No providers match: " + name);
11334                    pw.println("Use -h for help.");
11335                }
11336            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11337                synchronized (this) {
11338                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11339                }
11340            } else if ("service".equals(cmd)) {
11341                String[] newArgs;
11342                String name;
11343                if (opti >= args.length) {
11344                    name = null;
11345                    newArgs = EMPTY_STRING_ARRAY;
11346                } else {
11347                    name = args[opti];
11348                    opti++;
11349                    newArgs = new String[args.length - opti];
11350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11351                            args.length - opti);
11352                }
11353                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11354                    pw.println("No services match: " + name);
11355                    pw.println("Use -h for help.");
11356                }
11357            } else if ("package".equals(cmd)) {
11358                String[] newArgs;
11359                if (opti >= args.length) {
11360                    pw.println("package: no package name specified");
11361                    pw.println("Use -h for help.");
11362                } else {
11363                    dumpPackage = args[opti];
11364                    opti++;
11365                    newArgs = new String[args.length - opti];
11366                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11367                            args.length - opti);
11368                    args = newArgs;
11369                    opti = 0;
11370                    more = true;
11371                }
11372            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11373                synchronized (this) {
11374                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11375                }
11376            } else {
11377                // Dumping a single activity?
11378                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11379                    pw.println("Bad activity command, or no activities match: " + cmd);
11380                    pw.println("Use -h for help.");
11381                }
11382            }
11383            if (!more) {
11384                Binder.restoreCallingIdentity(origId);
11385                return;
11386            }
11387        }
11388
11389        // No piece of data specified, dump everything.
11390        synchronized (this) {
11391            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11392            pw.println();
11393            if (dumpAll) {
11394                pw.println("-------------------------------------------------------------------------------");
11395            }
11396            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11397            pw.println();
11398            if (dumpAll) {
11399                pw.println("-------------------------------------------------------------------------------");
11400            }
11401            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11402            pw.println();
11403            if (dumpAll) {
11404                pw.println("-------------------------------------------------------------------------------");
11405            }
11406            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11407            pw.println();
11408            if (dumpAll) {
11409                pw.println("-------------------------------------------------------------------------------");
11410            }
11411            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11412            pw.println();
11413            if (dumpAll) {
11414                pw.println("-------------------------------------------------------------------------------");
11415            }
11416            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11417        }
11418        Binder.restoreCallingIdentity(origId);
11419    }
11420
11421    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11422            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11423        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11424
11425        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11426                dumpPackage);
11427        boolean needSep = printedAnything;
11428
11429        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11430                dumpPackage, needSep, "  mFocusedActivity: ");
11431        if (printed) {
11432            printedAnything = true;
11433            needSep = false;
11434        }
11435
11436        if (dumpPackage == null) {
11437            if (needSep) {
11438                pw.println();
11439            }
11440            needSep = true;
11441            printedAnything = true;
11442            mStackSupervisor.dump(pw, "  ");
11443        }
11444
11445        if (mRecentTasks.size() > 0) {
11446            boolean printedHeader = false;
11447
11448            final int N = mRecentTasks.size();
11449            for (int i=0; i<N; i++) {
11450                TaskRecord tr = mRecentTasks.get(i);
11451                if (dumpPackage != null) {
11452                    if (tr.realActivity == null ||
11453                            !dumpPackage.equals(tr.realActivity)) {
11454                        continue;
11455                    }
11456                }
11457                if (!printedHeader) {
11458                    if (needSep) {
11459                        pw.println();
11460                    }
11461                    pw.println("  Recent tasks:");
11462                    printedHeader = true;
11463                    printedAnything = true;
11464                }
11465                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11466                        pw.println(tr);
11467                if (dumpAll) {
11468                    mRecentTasks.get(i).dump(pw, "    ");
11469                }
11470            }
11471        }
11472
11473        if (!printedAnything) {
11474            pw.println("  (nothing)");
11475        }
11476    }
11477
11478    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11479            int opti, boolean dumpAll, String dumpPackage) {
11480        boolean needSep = false;
11481        boolean printedAnything = false;
11482        int numPers = 0;
11483
11484        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11485
11486        if (dumpAll) {
11487            final int NP = mProcessNames.getMap().size();
11488            for (int ip=0; ip<NP; ip++) {
11489                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11490                final int NA = procs.size();
11491                for (int ia=0; ia<NA; ia++) {
11492                    ProcessRecord r = procs.valueAt(ia);
11493                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11494                        continue;
11495                    }
11496                    if (!needSep) {
11497                        pw.println("  All known processes:");
11498                        needSep = true;
11499                        printedAnything = true;
11500                    }
11501                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11502                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11503                        pw.print(" "); pw.println(r);
11504                    r.dump(pw, "    ");
11505                    if (r.persistent) {
11506                        numPers++;
11507                    }
11508                }
11509            }
11510        }
11511
11512        if (mIsolatedProcesses.size() > 0) {
11513            boolean printed = false;
11514            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11515                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11516                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11517                    continue;
11518                }
11519                if (!printed) {
11520                    if (needSep) {
11521                        pw.println();
11522                    }
11523                    pw.println("  Isolated process list (sorted by uid):");
11524                    printedAnything = true;
11525                    printed = true;
11526                    needSep = true;
11527                }
11528                pw.println(String.format("%sIsolated #%2d: %s",
11529                        "    ", i, r.toString()));
11530            }
11531        }
11532
11533        if (mLruProcesses.size() > 0) {
11534            if (needSep) {
11535                pw.println();
11536            }
11537            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11538                    pw.print(" total, non-act at ");
11539                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11540                    pw.print(", non-svc at ");
11541                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11542                    pw.println("):");
11543            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11544            needSep = true;
11545            printedAnything = true;
11546        }
11547
11548        if (dumpAll || dumpPackage != null) {
11549            synchronized (mPidsSelfLocked) {
11550                boolean printed = false;
11551                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11552                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11553                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11554                        continue;
11555                    }
11556                    if (!printed) {
11557                        if (needSep) pw.println();
11558                        needSep = true;
11559                        pw.println("  PID mappings:");
11560                        printed = true;
11561                        printedAnything = true;
11562                    }
11563                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11564                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11565                }
11566            }
11567        }
11568
11569        if (mForegroundProcesses.size() > 0) {
11570            synchronized (mPidsSelfLocked) {
11571                boolean printed = false;
11572                for (int i=0; i<mForegroundProcesses.size(); i++) {
11573                    ProcessRecord r = mPidsSelfLocked.get(
11574                            mForegroundProcesses.valueAt(i).pid);
11575                    if (dumpPackage != null && (r == null
11576                            || !r.pkgList.containsKey(dumpPackage))) {
11577                        continue;
11578                    }
11579                    if (!printed) {
11580                        if (needSep) pw.println();
11581                        needSep = true;
11582                        pw.println("  Foreground Processes:");
11583                        printed = true;
11584                        printedAnything = true;
11585                    }
11586                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11587                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11588                }
11589            }
11590        }
11591
11592        if (mPersistentStartingProcesses.size() > 0) {
11593            if (needSep) pw.println();
11594            needSep = true;
11595            printedAnything = true;
11596            pw.println("  Persisent processes that are starting:");
11597            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11598                    "Starting Norm", "Restarting PERS", dumpPackage);
11599        }
11600
11601        if (mRemovedProcesses.size() > 0) {
11602            if (needSep) pw.println();
11603            needSep = true;
11604            printedAnything = true;
11605            pw.println("  Processes that are being removed:");
11606            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11607                    "Removed Norm", "Removed PERS", dumpPackage);
11608        }
11609
11610        if (mProcessesOnHold.size() > 0) {
11611            if (needSep) pw.println();
11612            needSep = true;
11613            printedAnything = true;
11614            pw.println("  Processes that are on old until the system is ready:");
11615            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11616                    "OnHold Norm", "OnHold PERS", dumpPackage);
11617        }
11618
11619        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11620
11621        if (mProcessCrashTimes.getMap().size() > 0) {
11622            boolean printed = false;
11623            long now = SystemClock.uptimeMillis();
11624            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11625            final int NP = pmap.size();
11626            for (int ip=0; ip<NP; ip++) {
11627                String pname = pmap.keyAt(ip);
11628                SparseArray<Long> uids = pmap.valueAt(ip);
11629                final int N = uids.size();
11630                for (int i=0; i<N; i++) {
11631                    int puid = uids.keyAt(i);
11632                    ProcessRecord r = mProcessNames.get(pname, puid);
11633                    if (dumpPackage != null && (r == null
11634                            || !r.pkgList.containsKey(dumpPackage))) {
11635                        continue;
11636                    }
11637                    if (!printed) {
11638                        if (needSep) pw.println();
11639                        needSep = true;
11640                        pw.println("  Time since processes crashed:");
11641                        printed = true;
11642                        printedAnything = true;
11643                    }
11644                    pw.print("    Process "); pw.print(pname);
11645                            pw.print(" uid "); pw.print(puid);
11646                            pw.print(": last crashed ");
11647                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11648                            pw.println(" ago");
11649                }
11650            }
11651        }
11652
11653        if (mBadProcesses.getMap().size() > 0) {
11654            boolean printed = false;
11655            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11656            final int NP = pmap.size();
11657            for (int ip=0; ip<NP; ip++) {
11658                String pname = pmap.keyAt(ip);
11659                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11660                final int N = uids.size();
11661                for (int i=0; i<N; i++) {
11662                    int puid = uids.keyAt(i);
11663                    ProcessRecord r = mProcessNames.get(pname, puid);
11664                    if (dumpPackage != null && (r == null
11665                            || !r.pkgList.containsKey(dumpPackage))) {
11666                        continue;
11667                    }
11668                    if (!printed) {
11669                        if (needSep) pw.println();
11670                        needSep = true;
11671                        pw.println("  Bad processes:");
11672                        printedAnything = true;
11673                    }
11674                    BadProcessInfo info = uids.valueAt(i);
11675                    pw.print("    Bad process "); pw.print(pname);
11676                            pw.print(" uid "); pw.print(puid);
11677                            pw.print(": crashed at time "); pw.println(info.time);
11678                    if (info.shortMsg != null) {
11679                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11680                    }
11681                    if (info.longMsg != null) {
11682                        pw.print("      Long msg: "); pw.println(info.longMsg);
11683                    }
11684                    if (info.stack != null) {
11685                        pw.println("      Stack:");
11686                        int lastPos = 0;
11687                        for (int pos=0; pos<info.stack.length(); pos++) {
11688                            if (info.stack.charAt(pos) == '\n') {
11689                                pw.print("        ");
11690                                pw.write(info.stack, lastPos, pos-lastPos);
11691                                pw.println();
11692                                lastPos = pos+1;
11693                            }
11694                        }
11695                        if (lastPos < info.stack.length()) {
11696                            pw.print("        ");
11697                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11698                            pw.println();
11699                        }
11700                    }
11701                }
11702            }
11703        }
11704
11705        if (dumpPackage == null) {
11706            pw.println();
11707            needSep = false;
11708            pw.println("  mStartedUsers:");
11709            for (int i=0; i<mStartedUsers.size(); i++) {
11710                UserStartedState uss = mStartedUsers.valueAt(i);
11711                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11712                        pw.print(": "); uss.dump("", pw);
11713            }
11714            pw.print("  mStartedUserArray: [");
11715            for (int i=0; i<mStartedUserArray.length; i++) {
11716                if (i > 0) pw.print(", ");
11717                pw.print(mStartedUserArray[i]);
11718            }
11719            pw.println("]");
11720            pw.print("  mUserLru: [");
11721            for (int i=0; i<mUserLru.size(); i++) {
11722                if (i > 0) pw.print(", ");
11723                pw.print(mUserLru.get(i));
11724            }
11725            pw.println("]");
11726            if (dumpAll) {
11727                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11728            }
11729            synchronized (mUserProfileGroupIdsSelfLocked) {
11730                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11731                    pw.println("  mUserProfileGroupIds:");
11732                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11733                        pw.print("    User #");
11734                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11735                        pw.print(" -> profile #");
11736                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11737                    }
11738                }
11739            }
11740        }
11741        if (mHomeProcess != null && (dumpPackage == null
11742                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11743            if (needSep) {
11744                pw.println();
11745                needSep = false;
11746            }
11747            pw.println("  mHomeProcess: " + mHomeProcess);
11748        }
11749        if (mPreviousProcess != null && (dumpPackage == null
11750                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11751            if (needSep) {
11752                pw.println();
11753                needSep = false;
11754            }
11755            pw.println("  mPreviousProcess: " + mPreviousProcess);
11756        }
11757        if (dumpAll) {
11758            StringBuilder sb = new StringBuilder(128);
11759            sb.append("  mPreviousProcessVisibleTime: ");
11760            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11761            pw.println(sb);
11762        }
11763        if (mHeavyWeightProcess != null && (dumpPackage == null
11764                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11765            if (needSep) {
11766                pw.println();
11767                needSep = false;
11768            }
11769            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11770        }
11771        if (dumpPackage == null) {
11772            pw.println("  mConfiguration: " + mConfiguration);
11773        }
11774        if (dumpAll) {
11775            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11776            if (mCompatModePackages.getPackages().size() > 0) {
11777                boolean printed = false;
11778                for (Map.Entry<String, Integer> entry
11779                        : mCompatModePackages.getPackages().entrySet()) {
11780                    String pkg = entry.getKey();
11781                    int mode = entry.getValue();
11782                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11783                        continue;
11784                    }
11785                    if (!printed) {
11786                        pw.println("  mScreenCompatPackages:");
11787                        printed = true;
11788                    }
11789                    pw.print("    "); pw.print(pkg); pw.print(": ");
11790                            pw.print(mode); pw.println();
11791                }
11792            }
11793        }
11794        if (dumpPackage == null) {
11795            if (mSleeping || mWentToSleep || mLockScreenShown) {
11796                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11797                        + " mLockScreenShown " + mLockScreenShown);
11798            }
11799            if (mShuttingDown || mRunningVoice) {
11800                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11801            }
11802        }
11803        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11804                || mOrigWaitForDebugger) {
11805            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11806                    || dumpPackage.equals(mOrigDebugApp)) {
11807                if (needSep) {
11808                    pw.println();
11809                    needSep = false;
11810                }
11811                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11812                        + " mDebugTransient=" + mDebugTransient
11813                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11814            }
11815        }
11816        if (mOpenGlTraceApp != null) {
11817            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11818                if (needSep) {
11819                    pw.println();
11820                    needSep = false;
11821                }
11822                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11823            }
11824        }
11825        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11826                || mProfileFd != null) {
11827            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11828                if (needSep) {
11829                    pw.println();
11830                    needSep = false;
11831                }
11832                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11833                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11834                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11835                        + mAutoStopProfiler);
11836            }
11837        }
11838        if (dumpPackage == null) {
11839            if (mAlwaysFinishActivities || mController != null) {
11840                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11841                        + " mController=" + mController);
11842            }
11843            if (dumpAll) {
11844                pw.println("  Total persistent processes: " + numPers);
11845                pw.println("  mProcessesReady=" + mProcessesReady
11846                        + " mSystemReady=" + mSystemReady);
11847                pw.println("  mBooting=" + mBooting
11848                        + " mBooted=" + mBooted
11849                        + " mFactoryTest=" + mFactoryTest);
11850                pw.print("  mLastPowerCheckRealtime=");
11851                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11852                        pw.println("");
11853                pw.print("  mLastPowerCheckUptime=");
11854                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11855                        pw.println("");
11856                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11857                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11858                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11859                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11860                        + " (" + mLruProcesses.size() + " total)"
11861                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11862                        + " mNumServiceProcs=" + mNumServiceProcs
11863                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11864                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11865                        + " mLastMemoryLevel" + mLastMemoryLevel
11866                        + " mLastNumProcesses" + mLastNumProcesses);
11867                long now = SystemClock.uptimeMillis();
11868                pw.print("  mLastIdleTime=");
11869                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11870                        pw.print(" mLowRamSinceLastIdle=");
11871                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11872                        pw.println();
11873            }
11874        }
11875
11876        if (!printedAnything) {
11877            pw.println("  (nothing)");
11878        }
11879    }
11880
11881    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11882            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11883        if (mProcessesToGc.size() > 0) {
11884            boolean printed = false;
11885            long now = SystemClock.uptimeMillis();
11886            for (int i=0; i<mProcessesToGc.size(); i++) {
11887                ProcessRecord proc = mProcessesToGc.get(i);
11888                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11889                    continue;
11890                }
11891                if (!printed) {
11892                    if (needSep) pw.println();
11893                    needSep = true;
11894                    pw.println("  Processes that are waiting to GC:");
11895                    printed = true;
11896                }
11897                pw.print("    Process "); pw.println(proc);
11898                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11899                        pw.print(", last gced=");
11900                        pw.print(now-proc.lastRequestedGc);
11901                        pw.print(" ms ago, last lowMem=");
11902                        pw.print(now-proc.lastLowMemory);
11903                        pw.println(" ms ago");
11904
11905            }
11906        }
11907        return needSep;
11908    }
11909
11910    void printOomLevel(PrintWriter pw, String name, int adj) {
11911        pw.print("    ");
11912        if (adj >= 0) {
11913            pw.print(' ');
11914            if (adj < 10) pw.print(' ');
11915        } else {
11916            if (adj > -10) pw.print(' ');
11917        }
11918        pw.print(adj);
11919        pw.print(": ");
11920        pw.print(name);
11921        pw.print(" (");
11922        pw.print(mProcessList.getMemLevel(adj)/1024);
11923        pw.println(" kB)");
11924    }
11925
11926    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11927            int opti, boolean dumpAll) {
11928        boolean needSep = false;
11929
11930        if (mLruProcesses.size() > 0) {
11931            if (needSep) pw.println();
11932            needSep = true;
11933            pw.println("  OOM levels:");
11934            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11935            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11936            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11937            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11938            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11939            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11940            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11941            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11942            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11943            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11944            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11945            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11946            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11947
11948            if (needSep) pw.println();
11949            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11950                    pw.print(" total, non-act at ");
11951                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11952                    pw.print(", non-svc at ");
11953                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11954                    pw.println("):");
11955            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11956            needSep = true;
11957        }
11958
11959        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11960
11961        pw.println();
11962        pw.println("  mHomeProcess: " + mHomeProcess);
11963        pw.println("  mPreviousProcess: " + mPreviousProcess);
11964        if (mHeavyWeightProcess != null) {
11965            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11966        }
11967
11968        return true;
11969    }
11970
11971    /**
11972     * There are three ways to call this:
11973     *  - no provider specified: dump all the providers
11974     *  - a flattened component name that matched an existing provider was specified as the
11975     *    first arg: dump that one provider
11976     *  - the first arg isn't the flattened component name of an existing provider:
11977     *    dump all providers whose component contains the first arg as a substring
11978     */
11979    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11980            int opti, boolean dumpAll) {
11981        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11982    }
11983
11984    static class ItemMatcher {
11985        ArrayList<ComponentName> components;
11986        ArrayList<String> strings;
11987        ArrayList<Integer> objects;
11988        boolean all;
11989
11990        ItemMatcher() {
11991            all = true;
11992        }
11993
11994        void build(String name) {
11995            ComponentName componentName = ComponentName.unflattenFromString(name);
11996            if (componentName != null) {
11997                if (components == null) {
11998                    components = new ArrayList<ComponentName>();
11999                }
12000                components.add(componentName);
12001                all = false;
12002            } else {
12003                int objectId = 0;
12004                // Not a '/' separated full component name; maybe an object ID?
12005                try {
12006                    objectId = Integer.parseInt(name, 16);
12007                    if (objects == null) {
12008                        objects = new ArrayList<Integer>();
12009                    }
12010                    objects.add(objectId);
12011                    all = false;
12012                } catch (RuntimeException e) {
12013                    // Not an integer; just do string match.
12014                    if (strings == null) {
12015                        strings = new ArrayList<String>();
12016                    }
12017                    strings.add(name);
12018                    all = false;
12019                }
12020            }
12021        }
12022
12023        int build(String[] args, int opti) {
12024            for (; opti<args.length; opti++) {
12025                String name = args[opti];
12026                if ("--".equals(name)) {
12027                    return opti+1;
12028                }
12029                build(name);
12030            }
12031            return opti;
12032        }
12033
12034        boolean match(Object object, ComponentName comp) {
12035            if (all) {
12036                return true;
12037            }
12038            if (components != null) {
12039                for (int i=0; i<components.size(); i++) {
12040                    if (components.get(i).equals(comp)) {
12041                        return true;
12042                    }
12043                }
12044            }
12045            if (objects != null) {
12046                for (int i=0; i<objects.size(); i++) {
12047                    if (System.identityHashCode(object) == objects.get(i)) {
12048                        return true;
12049                    }
12050                }
12051            }
12052            if (strings != null) {
12053                String flat = comp.flattenToString();
12054                for (int i=0; i<strings.size(); i++) {
12055                    if (flat.contains(strings.get(i))) {
12056                        return true;
12057                    }
12058                }
12059            }
12060            return false;
12061        }
12062    }
12063
12064    /**
12065     * There are three things that cmd can be:
12066     *  - a flattened component name that matches an existing activity
12067     *  - the cmd arg isn't the flattened component name of an existing activity:
12068     *    dump all activity whose component contains the cmd as a substring
12069     *  - A hex number of the ActivityRecord object instance.
12070     */
12071    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12072            int opti, boolean dumpAll) {
12073        ArrayList<ActivityRecord> activities;
12074
12075        synchronized (this) {
12076            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12077        }
12078
12079        if (activities.size() <= 0) {
12080            return false;
12081        }
12082
12083        String[] newArgs = new String[args.length - opti];
12084        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12085
12086        TaskRecord lastTask = null;
12087        boolean needSep = false;
12088        for (int i=activities.size()-1; i>=0; i--) {
12089            ActivityRecord r = activities.get(i);
12090            if (needSep) {
12091                pw.println();
12092            }
12093            needSep = true;
12094            synchronized (this) {
12095                if (lastTask != r.task) {
12096                    lastTask = r.task;
12097                    pw.print("TASK "); pw.print(lastTask.affinity);
12098                            pw.print(" id="); pw.println(lastTask.taskId);
12099                    if (dumpAll) {
12100                        lastTask.dump(pw, "  ");
12101                    }
12102                }
12103            }
12104            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12105        }
12106        return true;
12107    }
12108
12109    /**
12110     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12111     * there is a thread associated with the activity.
12112     */
12113    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12114            final ActivityRecord r, String[] args, boolean dumpAll) {
12115        String innerPrefix = prefix + "  ";
12116        synchronized (this) {
12117            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12118                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12119                    pw.print(" pid=");
12120                    if (r.app != null) pw.println(r.app.pid);
12121                    else pw.println("(not running)");
12122            if (dumpAll) {
12123                r.dump(pw, innerPrefix);
12124            }
12125        }
12126        if (r.app != null && r.app.thread != null) {
12127            // flush anything that is already in the PrintWriter since the thread is going
12128            // to write to the file descriptor directly
12129            pw.flush();
12130            try {
12131                TransferPipe tp = new TransferPipe();
12132                try {
12133                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12134                            r.appToken, innerPrefix, args);
12135                    tp.go(fd);
12136                } finally {
12137                    tp.kill();
12138                }
12139            } catch (IOException e) {
12140                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12141            } catch (RemoteException e) {
12142                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12143            }
12144        }
12145    }
12146
12147    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12148            int opti, boolean dumpAll, String dumpPackage) {
12149        boolean needSep = false;
12150        boolean onlyHistory = false;
12151        boolean printedAnything = false;
12152
12153        if ("history".equals(dumpPackage)) {
12154            if (opti < args.length && "-s".equals(args[opti])) {
12155                dumpAll = false;
12156            }
12157            onlyHistory = true;
12158            dumpPackage = null;
12159        }
12160
12161        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12162        if (!onlyHistory && dumpAll) {
12163            if (mRegisteredReceivers.size() > 0) {
12164                boolean printed = false;
12165                Iterator it = mRegisteredReceivers.values().iterator();
12166                while (it.hasNext()) {
12167                    ReceiverList r = (ReceiverList)it.next();
12168                    if (dumpPackage != null && (r.app == null ||
12169                            !dumpPackage.equals(r.app.info.packageName))) {
12170                        continue;
12171                    }
12172                    if (!printed) {
12173                        pw.println("  Registered Receivers:");
12174                        needSep = true;
12175                        printed = true;
12176                        printedAnything = true;
12177                    }
12178                    pw.print("  * "); pw.println(r);
12179                    r.dump(pw, "    ");
12180                }
12181            }
12182
12183            if (mReceiverResolver.dump(pw, needSep ?
12184                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12185                    "    ", dumpPackage, false)) {
12186                needSep = true;
12187                printedAnything = true;
12188            }
12189        }
12190
12191        for (BroadcastQueue q : mBroadcastQueues) {
12192            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12193            printedAnything |= needSep;
12194        }
12195
12196        needSep = true;
12197
12198        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12199            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12200                if (needSep) {
12201                    pw.println();
12202                }
12203                needSep = true;
12204                printedAnything = true;
12205                pw.print("  Sticky broadcasts for user ");
12206                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12207                StringBuilder sb = new StringBuilder(128);
12208                for (Map.Entry<String, ArrayList<Intent>> ent
12209                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12210                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12211                    if (dumpAll) {
12212                        pw.println(":");
12213                        ArrayList<Intent> intents = ent.getValue();
12214                        final int N = intents.size();
12215                        for (int i=0; i<N; i++) {
12216                            sb.setLength(0);
12217                            sb.append("    Intent: ");
12218                            intents.get(i).toShortString(sb, false, true, false, false);
12219                            pw.println(sb.toString());
12220                            Bundle bundle = intents.get(i).getExtras();
12221                            if (bundle != null) {
12222                                pw.print("      ");
12223                                pw.println(bundle.toString());
12224                            }
12225                        }
12226                    } else {
12227                        pw.println("");
12228                    }
12229                }
12230            }
12231        }
12232
12233        if (!onlyHistory && dumpAll) {
12234            pw.println();
12235            for (BroadcastQueue queue : mBroadcastQueues) {
12236                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12237                        + queue.mBroadcastsScheduled);
12238            }
12239            pw.println("  mHandler:");
12240            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12241            needSep = true;
12242            printedAnything = true;
12243        }
12244
12245        if (!printedAnything) {
12246            pw.println("  (nothing)");
12247        }
12248    }
12249
12250    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12251            int opti, boolean dumpAll, String dumpPackage) {
12252        boolean needSep;
12253        boolean printedAnything = false;
12254
12255        ItemMatcher matcher = new ItemMatcher();
12256        matcher.build(args, opti);
12257
12258        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12259
12260        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12261        printedAnything |= needSep;
12262
12263        if (mLaunchingProviders.size() > 0) {
12264            boolean printed = false;
12265            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12266                ContentProviderRecord r = mLaunchingProviders.get(i);
12267                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12268                    continue;
12269                }
12270                if (!printed) {
12271                    if (needSep) pw.println();
12272                    needSep = true;
12273                    pw.println("  Launching content providers:");
12274                    printed = true;
12275                    printedAnything = true;
12276                }
12277                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12278                        pw.println(r);
12279            }
12280        }
12281
12282        if (mGrantedUriPermissions.size() > 0) {
12283            boolean printed = false;
12284            int dumpUid = -2;
12285            if (dumpPackage != null) {
12286                try {
12287                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12288                } catch (NameNotFoundException e) {
12289                    dumpUid = -1;
12290                }
12291            }
12292            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12293                int uid = mGrantedUriPermissions.keyAt(i);
12294                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12295                    continue;
12296                }
12297                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12298                if (!printed) {
12299                    if (needSep) pw.println();
12300                    needSep = true;
12301                    pw.println("  Granted Uri Permissions:");
12302                    printed = true;
12303                    printedAnything = true;
12304                }
12305                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12306                for (UriPermission perm : perms.values()) {
12307                    pw.print("    "); pw.println(perm);
12308                    if (dumpAll) {
12309                        perm.dump(pw, "      ");
12310                    }
12311                }
12312            }
12313        }
12314
12315        if (!printedAnything) {
12316            pw.println("  (nothing)");
12317        }
12318    }
12319
12320    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12321            int opti, boolean dumpAll, String dumpPackage) {
12322        boolean printed = false;
12323
12324        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12325
12326        if (mIntentSenderRecords.size() > 0) {
12327            Iterator<WeakReference<PendingIntentRecord>> it
12328                    = mIntentSenderRecords.values().iterator();
12329            while (it.hasNext()) {
12330                WeakReference<PendingIntentRecord> ref = it.next();
12331                PendingIntentRecord rec = ref != null ? ref.get(): null;
12332                if (dumpPackage != null && (rec == null
12333                        || !dumpPackage.equals(rec.key.packageName))) {
12334                    continue;
12335                }
12336                printed = true;
12337                if (rec != null) {
12338                    pw.print("  * "); pw.println(rec);
12339                    if (dumpAll) {
12340                        rec.dump(pw, "    ");
12341                    }
12342                } else {
12343                    pw.print("  * "); pw.println(ref);
12344                }
12345            }
12346        }
12347
12348        if (!printed) {
12349            pw.println("  (nothing)");
12350        }
12351    }
12352
12353    private static final int dumpProcessList(PrintWriter pw,
12354            ActivityManagerService service, List list,
12355            String prefix, String normalLabel, String persistentLabel,
12356            String dumpPackage) {
12357        int numPers = 0;
12358        final int N = list.size()-1;
12359        for (int i=N; i>=0; i--) {
12360            ProcessRecord r = (ProcessRecord)list.get(i);
12361            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12362                continue;
12363            }
12364            pw.println(String.format("%s%s #%2d: %s",
12365                    prefix, (r.persistent ? persistentLabel : normalLabel),
12366                    i, r.toString()));
12367            if (r.persistent) {
12368                numPers++;
12369            }
12370        }
12371        return numPers;
12372    }
12373
12374    private static final boolean dumpProcessOomList(PrintWriter pw,
12375            ActivityManagerService service, List<ProcessRecord> origList,
12376            String prefix, String normalLabel, String persistentLabel,
12377            boolean inclDetails, String dumpPackage) {
12378
12379        ArrayList<Pair<ProcessRecord, Integer>> list
12380                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12381        for (int i=0; i<origList.size(); i++) {
12382            ProcessRecord r = origList.get(i);
12383            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12384                continue;
12385            }
12386            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12387        }
12388
12389        if (list.size() <= 0) {
12390            return false;
12391        }
12392
12393        Comparator<Pair<ProcessRecord, Integer>> comparator
12394                = new Comparator<Pair<ProcessRecord, Integer>>() {
12395            @Override
12396            public int compare(Pair<ProcessRecord, Integer> object1,
12397                    Pair<ProcessRecord, Integer> object2) {
12398                if (object1.first.setAdj != object2.first.setAdj) {
12399                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12400                }
12401                if (object1.second.intValue() != object2.second.intValue()) {
12402                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12403                }
12404                return 0;
12405            }
12406        };
12407
12408        Collections.sort(list, comparator);
12409
12410        final long curRealtime = SystemClock.elapsedRealtime();
12411        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12412        final long curUptime = SystemClock.uptimeMillis();
12413        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12414
12415        for (int i=list.size()-1; i>=0; i--) {
12416            ProcessRecord r = list.get(i).first;
12417            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12418            char schedGroup;
12419            switch (r.setSchedGroup) {
12420                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12421                    schedGroup = 'B';
12422                    break;
12423                case Process.THREAD_GROUP_DEFAULT:
12424                    schedGroup = 'F';
12425                    break;
12426                default:
12427                    schedGroup = '?';
12428                    break;
12429            }
12430            char foreground;
12431            if (r.foregroundActivities) {
12432                foreground = 'A';
12433            } else if (r.foregroundServices) {
12434                foreground = 'S';
12435            } else {
12436                foreground = ' ';
12437            }
12438            String procState = ProcessList.makeProcStateString(r.curProcState);
12439            pw.print(prefix);
12440            pw.print(r.persistent ? persistentLabel : normalLabel);
12441            pw.print(" #");
12442            int num = (origList.size()-1)-list.get(i).second;
12443            if (num < 10) pw.print(' ');
12444            pw.print(num);
12445            pw.print(": ");
12446            pw.print(oomAdj);
12447            pw.print(' ');
12448            pw.print(schedGroup);
12449            pw.print('/');
12450            pw.print(foreground);
12451            pw.print('/');
12452            pw.print(procState);
12453            pw.print(" trm:");
12454            if (r.trimMemoryLevel < 10) pw.print(' ');
12455            pw.print(r.trimMemoryLevel);
12456            pw.print(' ');
12457            pw.print(r.toShortString());
12458            pw.print(" (");
12459            pw.print(r.adjType);
12460            pw.println(')');
12461            if (r.adjSource != null || r.adjTarget != null) {
12462                pw.print(prefix);
12463                pw.print("    ");
12464                if (r.adjTarget instanceof ComponentName) {
12465                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12466                } else if (r.adjTarget != null) {
12467                    pw.print(r.adjTarget.toString());
12468                } else {
12469                    pw.print("{null}");
12470                }
12471                pw.print("<=");
12472                if (r.adjSource instanceof ProcessRecord) {
12473                    pw.print("Proc{");
12474                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12475                    pw.println("}");
12476                } else if (r.adjSource != null) {
12477                    pw.println(r.adjSource.toString());
12478                } else {
12479                    pw.println("{null}");
12480                }
12481            }
12482            if (inclDetails) {
12483                pw.print(prefix);
12484                pw.print("    ");
12485                pw.print("oom: max="); pw.print(r.maxAdj);
12486                pw.print(" curRaw="); pw.print(r.curRawAdj);
12487                pw.print(" setRaw="); pw.print(r.setRawAdj);
12488                pw.print(" cur="); pw.print(r.curAdj);
12489                pw.print(" set="); pw.println(r.setAdj);
12490                pw.print(prefix);
12491                pw.print("    ");
12492                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12493                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12494                pw.print(" lastPss="); pw.print(r.lastPss);
12495                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12496                pw.print(prefix);
12497                pw.print("    ");
12498                pw.print("cached="); pw.print(r.cached);
12499                pw.print(" empty="); pw.print(r.empty);
12500                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12501
12502                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12503                    if (r.lastWakeTime != 0) {
12504                        long wtime;
12505                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12506                        synchronized (stats) {
12507                            wtime = stats.getProcessWakeTime(r.info.uid,
12508                                    r.pid, curRealtime);
12509                        }
12510                        long timeUsed = wtime - r.lastWakeTime;
12511                        pw.print(prefix);
12512                        pw.print("    ");
12513                        pw.print("keep awake over ");
12514                        TimeUtils.formatDuration(realtimeSince, pw);
12515                        pw.print(" used ");
12516                        TimeUtils.formatDuration(timeUsed, pw);
12517                        pw.print(" (");
12518                        pw.print((timeUsed*100)/realtimeSince);
12519                        pw.println("%)");
12520                    }
12521                    if (r.lastCpuTime != 0) {
12522                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12523                        pw.print(prefix);
12524                        pw.print("    ");
12525                        pw.print("run cpu over ");
12526                        TimeUtils.formatDuration(uptimeSince, pw);
12527                        pw.print(" used ");
12528                        TimeUtils.formatDuration(timeUsed, pw);
12529                        pw.print(" (");
12530                        pw.print((timeUsed*100)/uptimeSince);
12531                        pw.println("%)");
12532                    }
12533                }
12534            }
12535        }
12536        return true;
12537    }
12538
12539    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12540        ArrayList<ProcessRecord> procs;
12541        synchronized (this) {
12542            if (args != null && args.length > start
12543                    && args[start].charAt(0) != '-') {
12544                procs = new ArrayList<ProcessRecord>();
12545                int pid = -1;
12546                try {
12547                    pid = Integer.parseInt(args[start]);
12548                } catch (NumberFormatException e) {
12549                }
12550                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12551                    ProcessRecord proc = mLruProcesses.get(i);
12552                    if (proc.pid == pid) {
12553                        procs.add(proc);
12554                    } else if (proc.processName.equals(args[start])) {
12555                        procs.add(proc);
12556                    }
12557                }
12558                if (procs.size() <= 0) {
12559                    return null;
12560                }
12561            } else {
12562                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12563            }
12564        }
12565        return procs;
12566    }
12567
12568    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12569            PrintWriter pw, String[] args) {
12570        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12571        if (procs == null) {
12572            pw.println("No process found for: " + args[0]);
12573            return;
12574        }
12575
12576        long uptime = SystemClock.uptimeMillis();
12577        long realtime = SystemClock.elapsedRealtime();
12578        pw.println("Applications Graphics Acceleration Info:");
12579        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12580
12581        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12582            ProcessRecord r = procs.get(i);
12583            if (r.thread != null) {
12584                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12585                pw.flush();
12586                try {
12587                    TransferPipe tp = new TransferPipe();
12588                    try {
12589                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12590                        tp.go(fd);
12591                    } finally {
12592                        tp.kill();
12593                    }
12594                } catch (IOException e) {
12595                    pw.println("Failure while dumping the app: " + r);
12596                    pw.flush();
12597                } catch (RemoteException e) {
12598                    pw.println("Got a RemoteException while dumping the app " + r);
12599                    pw.flush();
12600                }
12601            }
12602        }
12603    }
12604
12605    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12606        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12607        if (procs == null) {
12608            pw.println("No process found for: " + args[0]);
12609            return;
12610        }
12611
12612        pw.println("Applications Database Info:");
12613
12614        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12615            ProcessRecord r = procs.get(i);
12616            if (r.thread != null) {
12617                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12618                pw.flush();
12619                try {
12620                    TransferPipe tp = new TransferPipe();
12621                    try {
12622                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12623                        tp.go(fd);
12624                    } finally {
12625                        tp.kill();
12626                    }
12627                } catch (IOException e) {
12628                    pw.println("Failure while dumping the app: " + r);
12629                    pw.flush();
12630                } catch (RemoteException e) {
12631                    pw.println("Got a RemoteException while dumping the app " + r);
12632                    pw.flush();
12633                }
12634            }
12635        }
12636    }
12637
12638    final static class MemItem {
12639        final boolean isProc;
12640        final String label;
12641        final String shortLabel;
12642        final long pss;
12643        final int id;
12644        final boolean hasActivities;
12645        ArrayList<MemItem> subitems;
12646
12647        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12648                boolean _hasActivities) {
12649            isProc = true;
12650            label = _label;
12651            shortLabel = _shortLabel;
12652            pss = _pss;
12653            id = _id;
12654            hasActivities = _hasActivities;
12655        }
12656
12657        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12658            isProc = false;
12659            label = _label;
12660            shortLabel = _shortLabel;
12661            pss = _pss;
12662            id = _id;
12663            hasActivities = false;
12664        }
12665    }
12666
12667    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12668            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12669        if (sort && !isCompact) {
12670            Collections.sort(items, new Comparator<MemItem>() {
12671                @Override
12672                public int compare(MemItem lhs, MemItem rhs) {
12673                    if (lhs.pss < rhs.pss) {
12674                        return 1;
12675                    } else if (lhs.pss > rhs.pss) {
12676                        return -1;
12677                    }
12678                    return 0;
12679                }
12680            });
12681        }
12682
12683        for (int i=0; i<items.size(); i++) {
12684            MemItem mi = items.get(i);
12685            if (!isCompact) {
12686                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12687            } else if (mi.isProc) {
12688                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12689                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12690                pw.println(mi.hasActivities ? ",a" : ",e");
12691            } else {
12692                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12693                pw.println(mi.pss);
12694            }
12695            if (mi.subitems != null) {
12696                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12697                        true, isCompact);
12698            }
12699        }
12700    }
12701
12702    // These are in KB.
12703    static final long[] DUMP_MEM_BUCKETS = new long[] {
12704        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12705        120*1024, 160*1024, 200*1024,
12706        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12707        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12708    };
12709
12710    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12711            boolean stackLike) {
12712        int start = label.lastIndexOf('.');
12713        if (start >= 0) start++;
12714        else start = 0;
12715        int end = label.length();
12716        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12717            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12718                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12719                out.append(bucket);
12720                out.append(stackLike ? "MB." : "MB ");
12721                out.append(label, start, end);
12722                return;
12723            }
12724        }
12725        out.append(memKB/1024);
12726        out.append(stackLike ? "MB." : "MB ");
12727        out.append(label, start, end);
12728    }
12729
12730    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12731            ProcessList.NATIVE_ADJ,
12732            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12733            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12734            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12735            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12736            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12737    };
12738    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12739            "Native",
12740            "System", "Persistent", "Foreground",
12741            "Visible", "Perceptible",
12742            "Heavy Weight", "Backup",
12743            "A Services", "Home",
12744            "Previous", "B Services", "Cached"
12745    };
12746    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12747            "native",
12748            "sys", "pers", "fore",
12749            "vis", "percept",
12750            "heavy", "backup",
12751            "servicea", "home",
12752            "prev", "serviceb", "cached"
12753    };
12754
12755    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12756            long realtime, boolean isCheckinRequest, boolean isCompact) {
12757        if (isCheckinRequest || isCompact) {
12758            // short checkin version
12759            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12760        } else {
12761            pw.println("Applications Memory Usage (kB):");
12762            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12763        }
12764    }
12765
12766    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12767            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12768        boolean dumpDetails = false;
12769        boolean dumpFullDetails = false;
12770        boolean dumpDalvik = false;
12771        boolean oomOnly = false;
12772        boolean isCompact = false;
12773        boolean localOnly = false;
12774
12775        int opti = 0;
12776        while (opti < args.length) {
12777            String opt = args[opti];
12778            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12779                break;
12780            }
12781            opti++;
12782            if ("-a".equals(opt)) {
12783                dumpDetails = true;
12784                dumpFullDetails = true;
12785                dumpDalvik = true;
12786            } else if ("-d".equals(opt)) {
12787                dumpDalvik = true;
12788            } else if ("-c".equals(opt)) {
12789                isCompact = true;
12790            } else if ("--oom".equals(opt)) {
12791                oomOnly = true;
12792            } else if ("--local".equals(opt)) {
12793                localOnly = true;
12794            } else if ("-h".equals(opt)) {
12795                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12796                pw.println("  -a: include all available information for each process.");
12797                pw.println("  -d: include dalvik details when dumping process details.");
12798                pw.println("  -c: dump in a compact machine-parseable representation.");
12799                pw.println("  --oom: only show processes organized by oom adj.");
12800                pw.println("  --local: only collect details locally, don't call process.");
12801                pw.println("If [process] is specified it can be the name or ");
12802                pw.println("pid of a specific process to dump.");
12803                return;
12804            } else {
12805                pw.println("Unknown argument: " + opt + "; use -h for help");
12806            }
12807        }
12808
12809        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12810        long uptime = SystemClock.uptimeMillis();
12811        long realtime = SystemClock.elapsedRealtime();
12812        final long[] tmpLong = new long[1];
12813
12814        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12815        if (procs == null) {
12816            // No Java processes.  Maybe they want to print a native process.
12817            if (args != null && args.length > opti
12818                    && args[opti].charAt(0) != '-') {
12819                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12820                        = new ArrayList<ProcessCpuTracker.Stats>();
12821                updateCpuStatsNow();
12822                int findPid = -1;
12823                try {
12824                    findPid = Integer.parseInt(args[opti]);
12825                } catch (NumberFormatException e) {
12826                }
12827                synchronized (mProcessCpuThread) {
12828                    final int N = mProcessCpuTracker.countStats();
12829                    for (int i=0; i<N; i++) {
12830                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12831                        if (st.pid == findPid || (st.baseName != null
12832                                && st.baseName.equals(args[opti]))) {
12833                            nativeProcs.add(st);
12834                        }
12835                    }
12836                }
12837                if (nativeProcs.size() > 0) {
12838                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12839                            isCompact);
12840                    Debug.MemoryInfo mi = null;
12841                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12842                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12843                        final int pid = r.pid;
12844                        if (!isCheckinRequest && dumpDetails) {
12845                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12846                        }
12847                        if (mi == null) {
12848                            mi = new Debug.MemoryInfo();
12849                        }
12850                        if (dumpDetails || (!brief && !oomOnly)) {
12851                            Debug.getMemoryInfo(pid, mi);
12852                        } else {
12853                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12854                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12855                        }
12856                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12857                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12858                        if (isCheckinRequest) {
12859                            pw.println();
12860                        }
12861                    }
12862                    return;
12863                }
12864            }
12865            pw.println("No process found for: " + args[opti]);
12866            return;
12867        }
12868
12869        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12870            dumpDetails = true;
12871        }
12872
12873        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12874
12875        String[] innerArgs = new String[args.length-opti];
12876        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12877
12878        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12879        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12880        long nativePss=0, dalvikPss=0, otherPss=0;
12881        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12882
12883        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12884        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12885                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12886
12887        long totalPss = 0;
12888        long cachedPss = 0;
12889
12890        Debug.MemoryInfo mi = null;
12891        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12892            final ProcessRecord r = procs.get(i);
12893            final IApplicationThread thread;
12894            final int pid;
12895            final int oomAdj;
12896            final boolean hasActivities;
12897            synchronized (this) {
12898                thread = r.thread;
12899                pid = r.pid;
12900                oomAdj = r.getSetAdjWithServices();
12901                hasActivities = r.activities.size() > 0;
12902            }
12903            if (thread != null) {
12904                if (!isCheckinRequest && dumpDetails) {
12905                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12906                }
12907                if (mi == null) {
12908                    mi = new Debug.MemoryInfo();
12909                }
12910                if (dumpDetails || (!brief && !oomOnly)) {
12911                    Debug.getMemoryInfo(pid, mi);
12912                } else {
12913                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12914                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12915                }
12916                if (dumpDetails) {
12917                    if (localOnly) {
12918                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12919                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12920                        if (isCheckinRequest) {
12921                            pw.println();
12922                        }
12923                    } else {
12924                        try {
12925                            pw.flush();
12926                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12927                                    dumpDalvik, innerArgs);
12928                        } catch (RemoteException e) {
12929                            if (!isCheckinRequest) {
12930                                pw.println("Got RemoteException!");
12931                                pw.flush();
12932                            }
12933                        }
12934                    }
12935                }
12936
12937                final long myTotalPss = mi.getTotalPss();
12938                final long myTotalUss = mi.getTotalUss();
12939
12940                synchronized (this) {
12941                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12942                        // Record this for posterity if the process has been stable.
12943                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12944                    }
12945                }
12946
12947                if (!isCheckinRequest && mi != null) {
12948                    totalPss += myTotalPss;
12949                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12950                            (hasActivities ? " / activities)" : ")"),
12951                            r.processName, myTotalPss, pid, hasActivities);
12952                    procMems.add(pssItem);
12953                    procMemsMap.put(pid, pssItem);
12954
12955                    nativePss += mi.nativePss;
12956                    dalvikPss += mi.dalvikPss;
12957                    otherPss += mi.otherPss;
12958                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12959                        long mem = mi.getOtherPss(j);
12960                        miscPss[j] += mem;
12961                        otherPss -= mem;
12962                    }
12963
12964                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12965                        cachedPss += myTotalPss;
12966                    }
12967
12968                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12969                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12970                                || oomIndex == (oomPss.length-1)) {
12971                            oomPss[oomIndex] += myTotalPss;
12972                            if (oomProcs[oomIndex] == null) {
12973                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12974                            }
12975                            oomProcs[oomIndex].add(pssItem);
12976                            break;
12977                        }
12978                    }
12979                }
12980            }
12981        }
12982
12983        long nativeProcTotalPss = 0;
12984
12985        if (!isCheckinRequest && procs.size() > 1) {
12986            // If we are showing aggregations, also look for native processes to
12987            // include so that our aggregations are more accurate.
12988            updateCpuStatsNow();
12989            synchronized (mProcessCpuThread) {
12990                final int N = mProcessCpuTracker.countStats();
12991                for (int i=0; i<N; i++) {
12992                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12993                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12994                        if (mi == null) {
12995                            mi = new Debug.MemoryInfo();
12996                        }
12997                        if (!brief && !oomOnly) {
12998                            Debug.getMemoryInfo(st.pid, mi);
12999                        } else {
13000                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13001                            mi.nativePrivateDirty = (int)tmpLong[0];
13002                        }
13003
13004                        final long myTotalPss = mi.getTotalPss();
13005                        totalPss += myTotalPss;
13006                        nativeProcTotalPss += myTotalPss;
13007
13008                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13009                                st.name, myTotalPss, st.pid, false);
13010                        procMems.add(pssItem);
13011
13012                        nativePss += mi.nativePss;
13013                        dalvikPss += mi.dalvikPss;
13014                        otherPss += mi.otherPss;
13015                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13016                            long mem = mi.getOtherPss(j);
13017                            miscPss[j] += mem;
13018                            otherPss -= mem;
13019                        }
13020                        oomPss[0] += myTotalPss;
13021                        if (oomProcs[0] == null) {
13022                            oomProcs[0] = new ArrayList<MemItem>();
13023                        }
13024                        oomProcs[0].add(pssItem);
13025                    }
13026                }
13027            }
13028
13029            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13030
13031            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13032            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13033            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13034            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13035                String label = Debug.MemoryInfo.getOtherLabel(j);
13036                catMems.add(new MemItem(label, label, miscPss[j], j));
13037            }
13038
13039            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13040            for (int j=0; j<oomPss.length; j++) {
13041                if (oomPss[j] != 0) {
13042                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13043                            : DUMP_MEM_OOM_LABEL[j];
13044                    MemItem item = new MemItem(label, label, oomPss[j],
13045                            DUMP_MEM_OOM_ADJ[j]);
13046                    item.subitems = oomProcs[j];
13047                    oomMems.add(item);
13048                }
13049            }
13050
13051            if (!brief && !oomOnly && !isCompact) {
13052                pw.println();
13053                pw.println("Total PSS by process:");
13054                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13055                pw.println();
13056            }
13057            if (!isCompact) {
13058                pw.println("Total PSS by OOM adjustment:");
13059            }
13060            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13061            if (!brief && !oomOnly) {
13062                PrintWriter out = categoryPw != null ? categoryPw : pw;
13063                if (!isCompact) {
13064                    out.println();
13065                    out.println("Total PSS by category:");
13066                }
13067                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13068            }
13069            if (!isCompact) {
13070                pw.println();
13071            }
13072            MemInfoReader memInfo = new MemInfoReader();
13073            memInfo.readMemInfo();
13074            if (nativeProcTotalPss > 0) {
13075                synchronized (this) {
13076                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13077                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13078                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13079                            nativeProcTotalPss);
13080                }
13081            }
13082            if (!brief) {
13083                if (!isCompact) {
13084                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13085                    pw.print(" kB (status ");
13086                    switch (mLastMemoryLevel) {
13087                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13088                            pw.println("normal)");
13089                            break;
13090                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13091                            pw.println("moderate)");
13092                            break;
13093                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13094                            pw.println("low)");
13095                            break;
13096                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13097                            pw.println("critical)");
13098                            break;
13099                        default:
13100                            pw.print(mLastMemoryLevel);
13101                            pw.println(")");
13102                            break;
13103                    }
13104                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13105                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13106                            pw.print(cachedPss); pw.print(" cached pss + ");
13107                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13108                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13109                } else {
13110                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13111                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13112                            + memInfo.getFreeSizeKb()); pw.print(",");
13113                    pw.println(totalPss - cachedPss);
13114                }
13115            }
13116            if (!isCompact) {
13117                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13118                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13119                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13120                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13121                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13122                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13123                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13124                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13125                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13126                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13127                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13128            }
13129            if (!brief) {
13130                if (memInfo.getZramTotalSizeKb() != 0) {
13131                    if (!isCompact) {
13132                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13133                                pw.print(" kB physical used for ");
13134                                pw.print(memInfo.getSwapTotalSizeKb()
13135                                        - memInfo.getSwapFreeSizeKb());
13136                                pw.print(" kB in swap (");
13137                                pw.print(memInfo.getSwapTotalSizeKb());
13138                                pw.println(" kB total swap)");
13139                    } else {
13140                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13141                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13142                                pw.println(memInfo.getSwapFreeSizeKb());
13143                    }
13144                }
13145                final int[] SINGLE_LONG_FORMAT = new int[] {
13146                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13147                };
13148                long[] longOut = new long[1];
13149                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13150                        SINGLE_LONG_FORMAT, null, longOut, null);
13151                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13152                longOut[0] = 0;
13153                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13154                        SINGLE_LONG_FORMAT, null, longOut, null);
13155                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13156                longOut[0] = 0;
13157                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13158                        SINGLE_LONG_FORMAT, null, longOut, null);
13159                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13160                longOut[0] = 0;
13161                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13162                        SINGLE_LONG_FORMAT, null, longOut, null);
13163                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13164                if (!isCompact) {
13165                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13166                        pw.print("      KSM: "); pw.print(sharing);
13167                                pw.print(" kB saved from shared ");
13168                                pw.print(shared); pw.println(" kB");
13169                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13170                                pw.print(voltile); pw.println(" kB volatile");
13171                    }
13172                    pw.print("   Tuning: ");
13173                    pw.print(ActivityManager.staticGetMemoryClass());
13174                    pw.print(" (large ");
13175                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13176                    pw.print("), oom ");
13177                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13178                    pw.print(" kB");
13179                    pw.print(", restore limit ");
13180                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13181                    pw.print(" kB");
13182                    if (ActivityManager.isLowRamDeviceStatic()) {
13183                        pw.print(" (low-ram)");
13184                    }
13185                    if (ActivityManager.isHighEndGfx()) {
13186                        pw.print(" (high-end-gfx)");
13187                    }
13188                    pw.println();
13189                } else {
13190                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13191                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13192                    pw.println(voltile);
13193                    pw.print("tuning,");
13194                    pw.print(ActivityManager.staticGetMemoryClass());
13195                    pw.print(',');
13196                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13197                    pw.print(',');
13198                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13199                    if (ActivityManager.isLowRamDeviceStatic()) {
13200                        pw.print(",low-ram");
13201                    }
13202                    if (ActivityManager.isHighEndGfx()) {
13203                        pw.print(",high-end-gfx");
13204                    }
13205                    pw.println();
13206                }
13207            }
13208        }
13209    }
13210
13211    /**
13212     * Searches array of arguments for the specified string
13213     * @param args array of argument strings
13214     * @param value value to search for
13215     * @return true if the value is contained in the array
13216     */
13217    private static boolean scanArgs(String[] args, String value) {
13218        if (args != null) {
13219            for (String arg : args) {
13220                if (value.equals(arg)) {
13221                    return true;
13222                }
13223            }
13224        }
13225        return false;
13226    }
13227
13228    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13229            ContentProviderRecord cpr, boolean always) {
13230        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13231
13232        if (!inLaunching || always) {
13233            synchronized (cpr) {
13234                cpr.launchingApp = null;
13235                cpr.notifyAll();
13236            }
13237            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13238            String names[] = cpr.info.authority.split(";");
13239            for (int j = 0; j < names.length; j++) {
13240                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13241            }
13242        }
13243
13244        for (int i=0; i<cpr.connections.size(); i++) {
13245            ContentProviderConnection conn = cpr.connections.get(i);
13246            if (conn.waiting) {
13247                // If this connection is waiting for the provider, then we don't
13248                // need to mess with its process unless we are always removing
13249                // or for some reason the provider is not currently launching.
13250                if (inLaunching && !always) {
13251                    continue;
13252                }
13253            }
13254            ProcessRecord capp = conn.client;
13255            conn.dead = true;
13256            if (conn.stableCount > 0) {
13257                if (!capp.persistent && capp.thread != null
13258                        && capp.pid != 0
13259                        && capp.pid != MY_PID) {
13260                    killUnneededProcessLocked(capp, "depends on provider "
13261                            + cpr.name.flattenToShortString()
13262                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13263                }
13264            } else if (capp.thread != null && conn.provider.provider != null) {
13265                try {
13266                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13267                } catch (RemoteException e) {
13268                }
13269                // In the protocol here, we don't expect the client to correctly
13270                // clean up this connection, we'll just remove it.
13271                cpr.connections.remove(i);
13272                conn.client.conProviders.remove(conn);
13273            }
13274        }
13275
13276        if (inLaunching && always) {
13277            mLaunchingProviders.remove(cpr);
13278        }
13279        return inLaunching;
13280    }
13281
13282    /**
13283     * Main code for cleaning up a process when it has gone away.  This is
13284     * called both as a result of the process dying, or directly when stopping
13285     * a process when running in single process mode.
13286     */
13287    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13288            boolean restarting, boolean allowRestart, int index) {
13289        if (index >= 0) {
13290            removeLruProcessLocked(app);
13291            ProcessList.remove(app.pid);
13292        }
13293
13294        mProcessesToGc.remove(app);
13295        mPendingPssProcesses.remove(app);
13296
13297        // Dismiss any open dialogs.
13298        if (app.crashDialog != null && !app.forceCrashReport) {
13299            app.crashDialog.dismiss();
13300            app.crashDialog = null;
13301        }
13302        if (app.anrDialog != null) {
13303            app.anrDialog.dismiss();
13304            app.anrDialog = null;
13305        }
13306        if (app.waitDialog != null) {
13307            app.waitDialog.dismiss();
13308            app.waitDialog = null;
13309        }
13310
13311        app.crashing = false;
13312        app.notResponding = false;
13313
13314        app.resetPackageList(mProcessStats);
13315        app.unlinkDeathRecipient();
13316        app.makeInactive(mProcessStats);
13317        app.waitingToKill = null;
13318        app.forcingToForeground = null;
13319        updateProcessForegroundLocked(app, false, false);
13320        app.foregroundActivities = false;
13321        app.hasShownUi = false;
13322        app.treatLikeActivity = false;
13323        app.hasAboveClient = false;
13324        app.hasClientActivities = false;
13325
13326        mServices.killServicesLocked(app, allowRestart);
13327
13328        boolean restart = false;
13329
13330        // Remove published content providers.
13331        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13332            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13333            final boolean always = app.bad || !allowRestart;
13334            if (removeDyingProviderLocked(app, cpr, always) || always) {
13335                // We left the provider in the launching list, need to
13336                // restart it.
13337                restart = true;
13338            }
13339
13340            cpr.provider = null;
13341            cpr.proc = null;
13342        }
13343        app.pubProviders.clear();
13344
13345        // Take care of any launching providers waiting for this process.
13346        if (checkAppInLaunchingProvidersLocked(app, false)) {
13347            restart = true;
13348        }
13349
13350        // Unregister from connected content providers.
13351        if (!app.conProviders.isEmpty()) {
13352            for (int i=0; i<app.conProviders.size(); i++) {
13353                ContentProviderConnection conn = app.conProviders.get(i);
13354                conn.provider.connections.remove(conn);
13355            }
13356            app.conProviders.clear();
13357        }
13358
13359        // At this point there may be remaining entries in mLaunchingProviders
13360        // where we were the only one waiting, so they are no longer of use.
13361        // Look for these and clean up if found.
13362        // XXX Commented out for now.  Trying to figure out a way to reproduce
13363        // the actual situation to identify what is actually going on.
13364        if (false) {
13365            for (int i=0; i<mLaunchingProviders.size(); i++) {
13366                ContentProviderRecord cpr = (ContentProviderRecord)
13367                        mLaunchingProviders.get(i);
13368                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13369                    synchronized (cpr) {
13370                        cpr.launchingApp = null;
13371                        cpr.notifyAll();
13372                    }
13373                }
13374            }
13375        }
13376
13377        skipCurrentReceiverLocked(app);
13378
13379        // Unregister any receivers.
13380        for (int i=app.receivers.size()-1; i>=0; i--) {
13381            removeReceiverLocked(app.receivers.valueAt(i));
13382        }
13383        app.receivers.clear();
13384
13385        // If the app is undergoing backup, tell the backup manager about it
13386        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13387            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13388                    + mBackupTarget.appInfo + " died during backup");
13389            try {
13390                IBackupManager bm = IBackupManager.Stub.asInterface(
13391                        ServiceManager.getService(Context.BACKUP_SERVICE));
13392                bm.agentDisconnected(app.info.packageName);
13393            } catch (RemoteException e) {
13394                // can't happen; backup manager is local
13395            }
13396        }
13397
13398        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13399            ProcessChangeItem item = mPendingProcessChanges.get(i);
13400            if (item.pid == app.pid) {
13401                mPendingProcessChanges.remove(i);
13402                mAvailProcessChanges.add(item);
13403            }
13404        }
13405        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13406
13407        // If the caller is restarting this app, then leave it in its
13408        // current lists and let the caller take care of it.
13409        if (restarting) {
13410            return;
13411        }
13412
13413        if (!app.persistent || app.isolated) {
13414            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13415                    "Removing non-persistent process during cleanup: " + app);
13416            mProcessNames.remove(app.processName, app.uid);
13417            mIsolatedProcesses.remove(app.uid);
13418            if (mHeavyWeightProcess == app) {
13419                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13420                        mHeavyWeightProcess.userId, 0));
13421                mHeavyWeightProcess = null;
13422            }
13423        } else if (!app.removed) {
13424            // This app is persistent, so we need to keep its record around.
13425            // If it is not already on the pending app list, add it there
13426            // and start a new process for it.
13427            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13428                mPersistentStartingProcesses.add(app);
13429                restart = true;
13430            }
13431        }
13432        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13433                "Clean-up removing on hold: " + app);
13434        mProcessesOnHold.remove(app);
13435
13436        if (app == mHomeProcess) {
13437            mHomeProcess = null;
13438        }
13439        if (app == mPreviousProcess) {
13440            mPreviousProcess = null;
13441        }
13442
13443        if (restart && !app.isolated) {
13444            // We have components that still need to be running in the
13445            // process, so re-launch it.
13446            mProcessNames.put(app.processName, app.uid, app);
13447            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13448        } else if (app.pid > 0 && app.pid != MY_PID) {
13449            // Goodbye!
13450            boolean removed;
13451            synchronized (mPidsSelfLocked) {
13452                mPidsSelfLocked.remove(app.pid);
13453                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13454            }
13455            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13456            if (app.isolated) {
13457                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13458            }
13459            app.setPid(0);
13460        }
13461    }
13462
13463    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13464        // Look through the content providers we are waiting to have launched,
13465        // and if any run in this process then either schedule a restart of
13466        // the process or kill the client waiting for it if this process has
13467        // gone bad.
13468        int NL = mLaunchingProviders.size();
13469        boolean restart = false;
13470        for (int i=0; i<NL; i++) {
13471            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13472            if (cpr.launchingApp == app) {
13473                if (!alwaysBad && !app.bad) {
13474                    restart = true;
13475                } else {
13476                    removeDyingProviderLocked(app, cpr, true);
13477                    // cpr should have been removed from mLaunchingProviders
13478                    NL = mLaunchingProviders.size();
13479                    i--;
13480                }
13481            }
13482        }
13483        return restart;
13484    }
13485
13486    // =========================================================
13487    // SERVICES
13488    // =========================================================
13489
13490    @Override
13491    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13492            int flags) {
13493        enforceNotIsolatedCaller("getServices");
13494        synchronized (this) {
13495            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13496        }
13497    }
13498
13499    @Override
13500    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13501        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13502        synchronized (this) {
13503            return mServices.getRunningServiceControlPanelLocked(name);
13504        }
13505    }
13506
13507    @Override
13508    public ComponentName startService(IApplicationThread caller, Intent service,
13509            String resolvedType, int userId) {
13510        enforceNotIsolatedCaller("startService");
13511        // Refuse possible leaked file descriptors
13512        if (service != null && service.hasFileDescriptors() == true) {
13513            throw new IllegalArgumentException("File descriptors passed in Intent");
13514        }
13515
13516        if (DEBUG_SERVICE)
13517            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13518        synchronized(this) {
13519            final int callingPid = Binder.getCallingPid();
13520            final int callingUid = Binder.getCallingUid();
13521            final long origId = Binder.clearCallingIdentity();
13522            ComponentName res = mServices.startServiceLocked(caller, service,
13523                    resolvedType, callingPid, callingUid, userId);
13524            Binder.restoreCallingIdentity(origId);
13525            return res;
13526        }
13527    }
13528
13529    ComponentName startServiceInPackage(int uid,
13530            Intent service, String resolvedType, int userId) {
13531        synchronized(this) {
13532            if (DEBUG_SERVICE)
13533                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13534            final long origId = Binder.clearCallingIdentity();
13535            ComponentName res = mServices.startServiceLocked(null, service,
13536                    resolvedType, -1, uid, userId);
13537            Binder.restoreCallingIdentity(origId);
13538            return res;
13539        }
13540    }
13541
13542    @Override
13543    public int stopService(IApplicationThread caller, Intent service,
13544            String resolvedType, int userId) {
13545        enforceNotIsolatedCaller("stopService");
13546        // Refuse possible leaked file descriptors
13547        if (service != null && service.hasFileDescriptors() == true) {
13548            throw new IllegalArgumentException("File descriptors passed in Intent");
13549        }
13550
13551        synchronized(this) {
13552            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13553        }
13554    }
13555
13556    @Override
13557    public IBinder peekService(Intent service, String resolvedType) {
13558        enforceNotIsolatedCaller("peekService");
13559        // Refuse possible leaked file descriptors
13560        if (service != null && service.hasFileDescriptors() == true) {
13561            throw new IllegalArgumentException("File descriptors passed in Intent");
13562        }
13563        synchronized(this) {
13564            return mServices.peekServiceLocked(service, resolvedType);
13565        }
13566    }
13567
13568    @Override
13569    public boolean stopServiceToken(ComponentName className, IBinder token,
13570            int startId) {
13571        synchronized(this) {
13572            return mServices.stopServiceTokenLocked(className, token, startId);
13573        }
13574    }
13575
13576    @Override
13577    public void setServiceForeground(ComponentName className, IBinder token,
13578            int id, Notification notification, boolean removeNotification) {
13579        synchronized(this) {
13580            mServices.setServiceForegroundLocked(className, token, id, notification,
13581                    removeNotification);
13582        }
13583    }
13584
13585    @Override
13586    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13587            boolean requireFull, String name, String callerPackage) {
13588        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13589                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13590    }
13591
13592    int unsafeConvertIncomingUser(int userId) {
13593        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13594                ? mCurrentUserId : userId;
13595    }
13596
13597    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13598            int allowMode, String name, String callerPackage) {
13599        final int callingUserId = UserHandle.getUserId(callingUid);
13600        if (callingUserId == userId) {
13601            return userId;
13602        }
13603
13604        // Note that we may be accessing mCurrentUserId outside of a lock...
13605        // shouldn't be a big deal, if this is being called outside
13606        // of a locked context there is intrinsically a race with
13607        // the value the caller will receive and someone else changing it.
13608        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13609        // we will switch to the calling user if access to the current user fails.
13610        int targetUserId = unsafeConvertIncomingUser(userId);
13611
13612        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13613            final boolean allow;
13614            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13615                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13616                // If the caller has this permission, they always pass go.  And collect $200.
13617                allow = true;
13618            } else if (allowMode == ALLOW_FULL_ONLY) {
13619                // We require full access, sucks to be you.
13620                allow = false;
13621            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13622                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13623                // If the caller does not have either permission, they are always doomed.
13624                allow = false;
13625            } else if (allowMode == ALLOW_NON_FULL) {
13626                // We are blanket allowing non-full access, you lucky caller!
13627                allow = true;
13628            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13629                // We may or may not allow this depending on whether the two users are
13630                // in the same profile.
13631                synchronized (mUserProfileGroupIdsSelfLocked) {
13632                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13633                            UserInfo.NO_PROFILE_GROUP_ID);
13634                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13635                            UserInfo.NO_PROFILE_GROUP_ID);
13636                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13637                            && callingProfile == targetProfile;
13638                }
13639            } else {
13640                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13641            }
13642            if (!allow) {
13643                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13644                    // In this case, they would like to just execute as their
13645                    // owner user instead of failing.
13646                    targetUserId = callingUserId;
13647                } else {
13648                    StringBuilder builder = new StringBuilder(128);
13649                    builder.append("Permission Denial: ");
13650                    builder.append(name);
13651                    if (callerPackage != null) {
13652                        builder.append(" from ");
13653                        builder.append(callerPackage);
13654                    }
13655                    builder.append(" asks to run as user ");
13656                    builder.append(userId);
13657                    builder.append(" but is calling from user ");
13658                    builder.append(UserHandle.getUserId(callingUid));
13659                    builder.append("; this requires ");
13660                    builder.append(INTERACT_ACROSS_USERS_FULL);
13661                    if (allowMode != ALLOW_FULL_ONLY) {
13662                        builder.append(" or ");
13663                        builder.append(INTERACT_ACROSS_USERS);
13664                    }
13665                    String msg = builder.toString();
13666                    Slog.w(TAG, msg);
13667                    throw new SecurityException(msg);
13668                }
13669            }
13670        }
13671        if (!allowAll && targetUserId < 0) {
13672            throw new IllegalArgumentException(
13673                    "Call does not support special user #" + targetUserId);
13674        }
13675        return targetUserId;
13676    }
13677
13678    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13679            String className, int flags) {
13680        boolean result = false;
13681        // For apps that don't have pre-defined UIDs, check for permission
13682        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13683            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13684                if (ActivityManager.checkUidPermission(
13685                        INTERACT_ACROSS_USERS,
13686                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13687                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13688                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13689                            + " requests FLAG_SINGLE_USER, but app does not hold "
13690                            + INTERACT_ACROSS_USERS;
13691                    Slog.w(TAG, msg);
13692                    throw new SecurityException(msg);
13693                }
13694                // Permission passed
13695                result = true;
13696            }
13697        } else if ("system".equals(componentProcessName)) {
13698            result = true;
13699        } else {
13700            // App with pre-defined UID, check if it's a persistent app
13701            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13702        }
13703        if (DEBUG_MU) {
13704            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13705                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13706        }
13707        return result;
13708    }
13709
13710    /**
13711     * Checks to see if the caller is in the same app as the singleton
13712     * component, or the component is in a special app. It allows special apps
13713     * to export singleton components but prevents exporting singleton
13714     * components for regular apps.
13715     */
13716    boolean isValidSingletonCall(int callingUid, int componentUid) {
13717        int componentAppId = UserHandle.getAppId(componentUid);
13718        return UserHandle.isSameApp(callingUid, componentUid)
13719                || componentAppId == Process.SYSTEM_UID
13720                || componentAppId == Process.PHONE_UID
13721                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13722                        == PackageManager.PERMISSION_GRANTED;
13723    }
13724
13725    public int bindService(IApplicationThread caller, IBinder token,
13726            Intent service, String resolvedType,
13727            IServiceConnection connection, int flags, int userId) {
13728        enforceNotIsolatedCaller("bindService");
13729        // Refuse possible leaked file descriptors
13730        if (service != null && service.hasFileDescriptors() == true) {
13731            throw new IllegalArgumentException("File descriptors passed in Intent");
13732        }
13733
13734        synchronized(this) {
13735            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13736                    connection, flags, userId);
13737        }
13738    }
13739
13740    public boolean unbindService(IServiceConnection connection) {
13741        synchronized (this) {
13742            return mServices.unbindServiceLocked(connection);
13743        }
13744    }
13745
13746    public void publishService(IBinder token, Intent intent, IBinder service) {
13747        // Refuse possible leaked file descriptors
13748        if (intent != null && intent.hasFileDescriptors() == true) {
13749            throw new IllegalArgumentException("File descriptors passed in Intent");
13750        }
13751
13752        synchronized(this) {
13753            if (!(token instanceof ServiceRecord)) {
13754                throw new IllegalArgumentException("Invalid service token");
13755            }
13756            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13757        }
13758    }
13759
13760    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13761        // Refuse possible leaked file descriptors
13762        if (intent != null && intent.hasFileDescriptors() == true) {
13763            throw new IllegalArgumentException("File descriptors passed in Intent");
13764        }
13765
13766        synchronized(this) {
13767            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13768        }
13769    }
13770
13771    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13772        synchronized(this) {
13773            if (!(token instanceof ServiceRecord)) {
13774                throw new IllegalArgumentException("Invalid service token");
13775            }
13776            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13777        }
13778    }
13779
13780    // =========================================================
13781    // BACKUP AND RESTORE
13782    // =========================================================
13783
13784    // Cause the target app to be launched if necessary and its backup agent
13785    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13786    // activity manager to announce its creation.
13787    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13788        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13789        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13790
13791        synchronized(this) {
13792            // !!! TODO: currently no check here that we're already bound
13793            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13794            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13795            synchronized (stats) {
13796                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13797            }
13798
13799            // Backup agent is now in use, its package can't be stopped.
13800            try {
13801                AppGlobals.getPackageManager().setPackageStoppedState(
13802                        app.packageName, false, UserHandle.getUserId(app.uid));
13803            } catch (RemoteException e) {
13804            } catch (IllegalArgumentException e) {
13805                Slog.w(TAG, "Failed trying to unstop package "
13806                        + app.packageName + ": " + e);
13807            }
13808
13809            BackupRecord r = new BackupRecord(ss, app, backupMode);
13810            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13811                    ? new ComponentName(app.packageName, app.backupAgentName)
13812                    : new ComponentName("android", "FullBackupAgent");
13813            // startProcessLocked() returns existing proc's record if it's already running
13814            ProcessRecord proc = startProcessLocked(app.processName, app,
13815                    false, 0, "backup", hostingName, false, false, false);
13816            if (proc == null) {
13817                Slog.e(TAG, "Unable to start backup agent process " + r);
13818                return false;
13819            }
13820
13821            r.app = proc;
13822            mBackupTarget = r;
13823            mBackupAppName = app.packageName;
13824
13825            // Try not to kill the process during backup
13826            updateOomAdjLocked(proc);
13827
13828            // If the process is already attached, schedule the creation of the backup agent now.
13829            // If it is not yet live, this will be done when it attaches to the framework.
13830            if (proc.thread != null) {
13831                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13832                try {
13833                    proc.thread.scheduleCreateBackupAgent(app,
13834                            compatibilityInfoForPackageLocked(app), backupMode);
13835                } catch (RemoteException e) {
13836                    // Will time out on the backup manager side
13837                }
13838            } else {
13839                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13840            }
13841            // Invariants: at this point, the target app process exists and the application
13842            // is either already running or in the process of coming up.  mBackupTarget and
13843            // mBackupAppName describe the app, so that when it binds back to the AM we
13844            // know that it's scheduled for a backup-agent operation.
13845        }
13846
13847        return true;
13848    }
13849
13850    @Override
13851    public void clearPendingBackup() {
13852        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13853        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13854
13855        synchronized (this) {
13856            mBackupTarget = null;
13857            mBackupAppName = null;
13858        }
13859    }
13860
13861    // A backup agent has just come up
13862    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13863        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13864                + " = " + agent);
13865
13866        synchronized(this) {
13867            if (!agentPackageName.equals(mBackupAppName)) {
13868                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13869                return;
13870            }
13871        }
13872
13873        long oldIdent = Binder.clearCallingIdentity();
13874        try {
13875            IBackupManager bm = IBackupManager.Stub.asInterface(
13876                    ServiceManager.getService(Context.BACKUP_SERVICE));
13877            bm.agentConnected(agentPackageName, agent);
13878        } catch (RemoteException e) {
13879            // can't happen; the backup manager service is local
13880        } catch (Exception e) {
13881            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13882            e.printStackTrace();
13883        } finally {
13884            Binder.restoreCallingIdentity(oldIdent);
13885        }
13886    }
13887
13888    // done with this agent
13889    public void unbindBackupAgent(ApplicationInfo appInfo) {
13890        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13891        if (appInfo == null) {
13892            Slog.w(TAG, "unbind backup agent for null app");
13893            return;
13894        }
13895
13896        synchronized(this) {
13897            try {
13898                if (mBackupAppName == null) {
13899                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13900                    return;
13901                }
13902
13903                if (!mBackupAppName.equals(appInfo.packageName)) {
13904                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13905                    return;
13906                }
13907
13908                // Not backing this app up any more; reset its OOM adjustment
13909                final ProcessRecord proc = mBackupTarget.app;
13910                updateOomAdjLocked(proc);
13911
13912                // If the app crashed during backup, 'thread' will be null here
13913                if (proc.thread != null) {
13914                    try {
13915                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13916                                compatibilityInfoForPackageLocked(appInfo));
13917                    } catch (Exception e) {
13918                        Slog.e(TAG, "Exception when unbinding backup agent:");
13919                        e.printStackTrace();
13920                    }
13921                }
13922            } finally {
13923                mBackupTarget = null;
13924                mBackupAppName = null;
13925            }
13926        }
13927    }
13928    // =========================================================
13929    // BROADCASTS
13930    // =========================================================
13931
13932    private final List getStickiesLocked(String action, IntentFilter filter,
13933            List cur, int userId) {
13934        final ContentResolver resolver = mContext.getContentResolver();
13935        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13936        if (stickies == null) {
13937            return cur;
13938        }
13939        final ArrayList<Intent> list = stickies.get(action);
13940        if (list == null) {
13941            return cur;
13942        }
13943        int N = list.size();
13944        for (int i=0; i<N; i++) {
13945            Intent intent = list.get(i);
13946            if (filter.match(resolver, intent, true, TAG) >= 0) {
13947                if (cur == null) {
13948                    cur = new ArrayList<Intent>();
13949                }
13950                cur.add(intent);
13951            }
13952        }
13953        return cur;
13954    }
13955
13956    boolean isPendingBroadcastProcessLocked(int pid) {
13957        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13958                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13959    }
13960
13961    void skipPendingBroadcastLocked(int pid) {
13962            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13963            for (BroadcastQueue queue : mBroadcastQueues) {
13964                queue.skipPendingBroadcastLocked(pid);
13965            }
13966    }
13967
13968    // The app just attached; send any pending broadcasts that it should receive
13969    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13970        boolean didSomething = false;
13971        for (BroadcastQueue queue : mBroadcastQueues) {
13972            didSomething |= queue.sendPendingBroadcastsLocked(app);
13973        }
13974        return didSomething;
13975    }
13976
13977    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13978            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13979        enforceNotIsolatedCaller("registerReceiver");
13980        int callingUid;
13981        int callingPid;
13982        synchronized(this) {
13983            ProcessRecord callerApp = null;
13984            if (caller != null) {
13985                callerApp = getRecordForAppLocked(caller);
13986                if (callerApp == null) {
13987                    throw new SecurityException(
13988                            "Unable to find app for caller " + caller
13989                            + " (pid=" + Binder.getCallingPid()
13990                            + ") when registering receiver " + receiver);
13991                }
13992                if (callerApp.info.uid != Process.SYSTEM_UID &&
13993                        !callerApp.pkgList.containsKey(callerPackage) &&
13994                        !"android".equals(callerPackage)) {
13995                    throw new SecurityException("Given caller package " + callerPackage
13996                            + " is not running in process " + callerApp);
13997                }
13998                callingUid = callerApp.info.uid;
13999                callingPid = callerApp.pid;
14000            } else {
14001                callerPackage = null;
14002                callingUid = Binder.getCallingUid();
14003                callingPid = Binder.getCallingPid();
14004            }
14005
14006            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14007                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14008
14009            List allSticky = null;
14010
14011            // Look for any matching sticky broadcasts...
14012            Iterator actions = filter.actionsIterator();
14013            if (actions != null) {
14014                while (actions.hasNext()) {
14015                    String action = (String)actions.next();
14016                    allSticky = getStickiesLocked(action, filter, allSticky,
14017                            UserHandle.USER_ALL);
14018                    allSticky = getStickiesLocked(action, filter, allSticky,
14019                            UserHandle.getUserId(callingUid));
14020                }
14021            } else {
14022                allSticky = getStickiesLocked(null, filter, allSticky,
14023                        UserHandle.USER_ALL);
14024                allSticky = getStickiesLocked(null, filter, allSticky,
14025                        UserHandle.getUserId(callingUid));
14026            }
14027
14028            // The first sticky in the list is returned directly back to
14029            // the client.
14030            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14031
14032            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14033                    + ": " + sticky);
14034
14035            if (receiver == null) {
14036                return sticky;
14037            }
14038
14039            ReceiverList rl
14040                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14041            if (rl == null) {
14042                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14043                        userId, receiver);
14044                if (rl.app != null) {
14045                    rl.app.receivers.add(rl);
14046                } else {
14047                    try {
14048                        receiver.asBinder().linkToDeath(rl, 0);
14049                    } catch (RemoteException e) {
14050                        return sticky;
14051                    }
14052                    rl.linkedToDeath = true;
14053                }
14054                mRegisteredReceivers.put(receiver.asBinder(), rl);
14055            } else if (rl.uid != callingUid) {
14056                throw new IllegalArgumentException(
14057                        "Receiver requested to register for uid " + callingUid
14058                        + " was previously registered for uid " + rl.uid);
14059            } else if (rl.pid != callingPid) {
14060                throw new IllegalArgumentException(
14061                        "Receiver requested to register for pid " + callingPid
14062                        + " was previously registered for pid " + rl.pid);
14063            } else if (rl.userId != userId) {
14064                throw new IllegalArgumentException(
14065                        "Receiver requested to register for user " + userId
14066                        + " was previously registered for user " + rl.userId);
14067            }
14068            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14069                    permission, callingUid, userId);
14070            rl.add(bf);
14071            if (!bf.debugCheck()) {
14072                Slog.w(TAG, "==> For Dynamic broadast");
14073            }
14074            mReceiverResolver.addFilter(bf);
14075
14076            // Enqueue broadcasts for all existing stickies that match
14077            // this filter.
14078            if (allSticky != null) {
14079                ArrayList receivers = new ArrayList();
14080                receivers.add(bf);
14081
14082                int N = allSticky.size();
14083                for (int i=0; i<N; i++) {
14084                    Intent intent = (Intent)allSticky.get(i);
14085                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14086                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14087                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14088                            null, null, false, true, true, -1);
14089                    queue.enqueueParallelBroadcastLocked(r);
14090                    queue.scheduleBroadcastsLocked();
14091                }
14092            }
14093
14094            return sticky;
14095        }
14096    }
14097
14098    public void unregisterReceiver(IIntentReceiver receiver) {
14099        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14100
14101        final long origId = Binder.clearCallingIdentity();
14102        try {
14103            boolean doTrim = false;
14104
14105            synchronized(this) {
14106                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14107                if (rl != null) {
14108                    if (rl.curBroadcast != null) {
14109                        BroadcastRecord r = rl.curBroadcast;
14110                        final boolean doNext = finishReceiverLocked(
14111                                receiver.asBinder(), r.resultCode, r.resultData,
14112                                r.resultExtras, r.resultAbort);
14113                        if (doNext) {
14114                            doTrim = true;
14115                            r.queue.processNextBroadcast(false);
14116                        }
14117                    }
14118
14119                    if (rl.app != null) {
14120                        rl.app.receivers.remove(rl);
14121                    }
14122                    removeReceiverLocked(rl);
14123                    if (rl.linkedToDeath) {
14124                        rl.linkedToDeath = false;
14125                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14126                    }
14127                }
14128            }
14129
14130            // If we actually concluded any broadcasts, we might now be able
14131            // to trim the recipients' apps from our working set
14132            if (doTrim) {
14133                trimApplications();
14134                return;
14135            }
14136
14137        } finally {
14138            Binder.restoreCallingIdentity(origId);
14139        }
14140    }
14141
14142    void removeReceiverLocked(ReceiverList rl) {
14143        mRegisteredReceivers.remove(rl.receiver.asBinder());
14144        int N = rl.size();
14145        for (int i=0; i<N; i++) {
14146            mReceiverResolver.removeFilter(rl.get(i));
14147        }
14148    }
14149
14150    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14151        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14152            ProcessRecord r = mLruProcesses.get(i);
14153            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14154                try {
14155                    r.thread.dispatchPackageBroadcast(cmd, packages);
14156                } catch (RemoteException ex) {
14157                }
14158            }
14159        }
14160    }
14161
14162    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14163            int[] users) {
14164        List<ResolveInfo> receivers = null;
14165        try {
14166            HashSet<ComponentName> singleUserReceivers = null;
14167            boolean scannedFirstReceivers = false;
14168            for (int user : users) {
14169                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14170                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14171                if (user != 0 && newReceivers != null) {
14172                    // If this is not the primary user, we need to check for
14173                    // any receivers that should be filtered out.
14174                    for (int i=0; i<newReceivers.size(); i++) {
14175                        ResolveInfo ri = newReceivers.get(i);
14176                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14177                            newReceivers.remove(i);
14178                            i--;
14179                        }
14180                    }
14181                }
14182                if (newReceivers != null && newReceivers.size() == 0) {
14183                    newReceivers = null;
14184                }
14185                if (receivers == null) {
14186                    receivers = newReceivers;
14187                } else if (newReceivers != null) {
14188                    // We need to concatenate the additional receivers
14189                    // found with what we have do far.  This would be easy,
14190                    // but we also need to de-dup any receivers that are
14191                    // singleUser.
14192                    if (!scannedFirstReceivers) {
14193                        // Collect any single user receivers we had already retrieved.
14194                        scannedFirstReceivers = true;
14195                        for (int i=0; i<receivers.size(); i++) {
14196                            ResolveInfo ri = receivers.get(i);
14197                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14198                                ComponentName cn = new ComponentName(
14199                                        ri.activityInfo.packageName, ri.activityInfo.name);
14200                                if (singleUserReceivers == null) {
14201                                    singleUserReceivers = new HashSet<ComponentName>();
14202                                }
14203                                singleUserReceivers.add(cn);
14204                            }
14205                        }
14206                    }
14207                    // Add the new results to the existing results, tracking
14208                    // and de-dupping single user receivers.
14209                    for (int i=0; i<newReceivers.size(); i++) {
14210                        ResolveInfo ri = newReceivers.get(i);
14211                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14212                            ComponentName cn = new ComponentName(
14213                                    ri.activityInfo.packageName, ri.activityInfo.name);
14214                            if (singleUserReceivers == null) {
14215                                singleUserReceivers = new HashSet<ComponentName>();
14216                            }
14217                            if (!singleUserReceivers.contains(cn)) {
14218                                singleUserReceivers.add(cn);
14219                                receivers.add(ri);
14220                            }
14221                        } else {
14222                            receivers.add(ri);
14223                        }
14224                    }
14225                }
14226            }
14227        } catch (RemoteException ex) {
14228            // pm is in same process, this will never happen.
14229        }
14230        return receivers;
14231    }
14232
14233    private final int broadcastIntentLocked(ProcessRecord callerApp,
14234            String callerPackage, Intent intent, String resolvedType,
14235            IIntentReceiver resultTo, int resultCode, String resultData,
14236            Bundle map, String requiredPermission, int appOp,
14237            boolean ordered, boolean sticky, int callingPid, int callingUid,
14238            int userId) {
14239        intent = new Intent(intent);
14240
14241        // By default broadcasts do not go to stopped apps.
14242        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14243
14244        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14245            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14246            + " ordered=" + ordered + " userid=" + userId);
14247        if ((resultTo != null) && !ordered) {
14248            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14249        }
14250
14251        userId = handleIncomingUser(callingPid, callingUid, userId,
14252                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14253
14254        // Make sure that the user who is receiving this broadcast is started.
14255        // If not, we will just skip it.
14256
14257
14258        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14259            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14260                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14261                Slog.w(TAG, "Skipping broadcast of " + intent
14262                        + ": user " + userId + " is stopped");
14263                return ActivityManager.BROADCAST_SUCCESS;
14264            }
14265        }
14266
14267        /*
14268         * Prevent non-system code (defined here to be non-persistent
14269         * processes) from sending protected broadcasts.
14270         */
14271        int callingAppId = UserHandle.getAppId(callingUid);
14272        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14273            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14274            || callingAppId == Process.NFC_UID || callingUid == 0) {
14275            // Always okay.
14276        } else if (callerApp == null || !callerApp.persistent) {
14277            try {
14278                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14279                        intent.getAction())) {
14280                    String msg = "Permission Denial: not allowed to send broadcast "
14281                            + intent.getAction() + " from pid="
14282                            + callingPid + ", uid=" + callingUid;
14283                    Slog.w(TAG, msg);
14284                    throw new SecurityException(msg);
14285                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14286                    // Special case for compatibility: we don't want apps to send this,
14287                    // but historically it has not been protected and apps may be using it
14288                    // to poke their own app widget.  So, instead of making it protected,
14289                    // just limit it to the caller.
14290                    if (callerApp == null) {
14291                        String msg = "Permission Denial: not allowed to send broadcast "
14292                                + intent.getAction() + " from unknown caller.";
14293                        Slog.w(TAG, msg);
14294                        throw new SecurityException(msg);
14295                    } else if (intent.getComponent() != null) {
14296                        // They are good enough to send to an explicit component...  verify
14297                        // it is being sent to the calling app.
14298                        if (!intent.getComponent().getPackageName().equals(
14299                                callerApp.info.packageName)) {
14300                            String msg = "Permission Denial: not allowed to send broadcast "
14301                                    + intent.getAction() + " to "
14302                                    + intent.getComponent().getPackageName() + " from "
14303                                    + callerApp.info.packageName;
14304                            Slog.w(TAG, msg);
14305                            throw new SecurityException(msg);
14306                        }
14307                    } else {
14308                        // Limit broadcast to their own package.
14309                        intent.setPackage(callerApp.info.packageName);
14310                    }
14311                }
14312            } catch (RemoteException e) {
14313                Slog.w(TAG, "Remote exception", e);
14314                return ActivityManager.BROADCAST_SUCCESS;
14315            }
14316        }
14317
14318        // Handle special intents: if this broadcast is from the package
14319        // manager about a package being removed, we need to remove all of
14320        // its activities from the history stack.
14321        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14322                intent.getAction());
14323        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14324                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14325                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14326                || uidRemoved) {
14327            if (checkComponentPermission(
14328                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14329                    callingPid, callingUid, -1, true)
14330                    == PackageManager.PERMISSION_GRANTED) {
14331                if (uidRemoved) {
14332                    final Bundle intentExtras = intent.getExtras();
14333                    final int uid = intentExtras != null
14334                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14335                    if (uid >= 0) {
14336                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14337                        synchronized (bs) {
14338                            bs.removeUidStatsLocked(uid);
14339                        }
14340                        mAppOpsService.uidRemoved(uid);
14341                    }
14342                } else {
14343                    // If resources are unavailable just force stop all
14344                    // those packages and flush the attribute cache as well.
14345                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14346                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14347                        if (list != null && (list.length > 0)) {
14348                            for (String pkg : list) {
14349                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14350                                        "storage unmount");
14351                            }
14352                            sendPackageBroadcastLocked(
14353                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14354                        }
14355                    } else {
14356                        Uri data = intent.getData();
14357                        String ssp;
14358                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14359                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14360                                    intent.getAction());
14361                            boolean fullUninstall = removed &&
14362                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14363                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14364                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14365                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14366                                        false, fullUninstall, userId,
14367                                        removed ? "pkg removed" : "pkg changed");
14368                            }
14369                            if (removed) {
14370                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14371                                        new String[] {ssp}, userId);
14372                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14373                                    mAppOpsService.packageRemoved(
14374                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14375
14376                                    // Remove all permissions granted from/to this package
14377                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14378                                }
14379                            }
14380                        }
14381                    }
14382                }
14383            } else {
14384                String msg = "Permission Denial: " + intent.getAction()
14385                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14386                        + ", uid=" + callingUid + ")"
14387                        + " requires "
14388                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14389                Slog.w(TAG, msg);
14390                throw new SecurityException(msg);
14391            }
14392
14393        // Special case for adding a package: by default turn on compatibility
14394        // mode.
14395        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14396            Uri data = intent.getData();
14397            String ssp;
14398            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14399                mCompatModePackages.handlePackageAddedLocked(ssp,
14400                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14401            }
14402        }
14403
14404        /*
14405         * If this is the time zone changed action, queue up a message that will reset the timezone
14406         * of all currently running processes. This message will get queued up before the broadcast
14407         * happens.
14408         */
14409        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14410            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14411        }
14412
14413        /*
14414         * If the user set the time, let all running processes know.
14415         */
14416        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14417            final int is24Hour = intent.getBooleanExtra(
14418                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14419            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14420        }
14421
14422        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14423            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14424        }
14425
14426        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14427            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14428            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14429        }
14430
14431        // Add to the sticky list if requested.
14432        if (sticky) {
14433            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14434                    callingPid, callingUid)
14435                    != PackageManager.PERMISSION_GRANTED) {
14436                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14437                        + callingPid + ", uid=" + callingUid
14438                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14439                Slog.w(TAG, msg);
14440                throw new SecurityException(msg);
14441            }
14442            if (requiredPermission != null) {
14443                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14444                        + " and enforce permission " + requiredPermission);
14445                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14446            }
14447            if (intent.getComponent() != null) {
14448                throw new SecurityException(
14449                        "Sticky broadcasts can't target a specific component");
14450            }
14451            // We use userId directly here, since the "all" target is maintained
14452            // as a separate set of sticky broadcasts.
14453            if (userId != UserHandle.USER_ALL) {
14454                // But first, if this is not a broadcast to all users, then
14455                // make sure it doesn't conflict with an existing broadcast to
14456                // all users.
14457                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14458                        UserHandle.USER_ALL);
14459                if (stickies != null) {
14460                    ArrayList<Intent> list = stickies.get(intent.getAction());
14461                    if (list != null) {
14462                        int N = list.size();
14463                        int i;
14464                        for (i=0; i<N; i++) {
14465                            if (intent.filterEquals(list.get(i))) {
14466                                throw new IllegalArgumentException(
14467                                        "Sticky broadcast " + intent + " for user "
14468                                        + userId + " conflicts with existing global broadcast");
14469                            }
14470                        }
14471                    }
14472                }
14473            }
14474            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14475            if (stickies == null) {
14476                stickies = new ArrayMap<String, ArrayList<Intent>>();
14477                mStickyBroadcasts.put(userId, stickies);
14478            }
14479            ArrayList<Intent> list = stickies.get(intent.getAction());
14480            if (list == null) {
14481                list = new ArrayList<Intent>();
14482                stickies.put(intent.getAction(), list);
14483            }
14484            int N = list.size();
14485            int i;
14486            for (i=0; i<N; i++) {
14487                if (intent.filterEquals(list.get(i))) {
14488                    // This sticky already exists, replace it.
14489                    list.set(i, new Intent(intent));
14490                    break;
14491                }
14492            }
14493            if (i >= N) {
14494                list.add(new Intent(intent));
14495            }
14496        }
14497
14498        int[] users;
14499        if (userId == UserHandle.USER_ALL) {
14500            // Caller wants broadcast to go to all started users.
14501            users = mStartedUserArray;
14502        } else {
14503            // Caller wants broadcast to go to one specific user.
14504            users = new int[] {userId};
14505        }
14506
14507        // Figure out who all will receive this broadcast.
14508        List receivers = null;
14509        List<BroadcastFilter> registeredReceivers = null;
14510        // Need to resolve the intent to interested receivers...
14511        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14512                 == 0) {
14513            receivers = collectReceiverComponents(intent, resolvedType, users);
14514        }
14515        if (intent.getComponent() == null) {
14516            registeredReceivers = mReceiverResolver.queryIntent(intent,
14517                    resolvedType, false, userId);
14518        }
14519
14520        final boolean replacePending =
14521                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14522
14523        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14524                + " replacePending=" + replacePending);
14525
14526        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14527        if (!ordered && NR > 0) {
14528            // If we are not serializing this broadcast, then send the
14529            // registered receivers separately so they don't wait for the
14530            // components to be launched.
14531            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14532            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14533                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14534                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14535                    ordered, sticky, false, userId);
14536            if (DEBUG_BROADCAST) Slog.v(
14537                    TAG, "Enqueueing parallel broadcast " + r);
14538            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14539            if (!replaced) {
14540                queue.enqueueParallelBroadcastLocked(r);
14541                queue.scheduleBroadcastsLocked();
14542            }
14543            registeredReceivers = null;
14544            NR = 0;
14545        }
14546
14547        // Merge into one list.
14548        int ir = 0;
14549        if (receivers != null) {
14550            // A special case for PACKAGE_ADDED: do not allow the package
14551            // being added to see this broadcast.  This prevents them from
14552            // using this as a back door to get run as soon as they are
14553            // installed.  Maybe in the future we want to have a special install
14554            // broadcast or such for apps, but we'd like to deliberately make
14555            // this decision.
14556            String skipPackages[] = null;
14557            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14558                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14559                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14560                Uri data = intent.getData();
14561                if (data != null) {
14562                    String pkgName = data.getSchemeSpecificPart();
14563                    if (pkgName != null) {
14564                        skipPackages = new String[] { pkgName };
14565                    }
14566                }
14567            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14568                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14569            }
14570            if (skipPackages != null && (skipPackages.length > 0)) {
14571                for (String skipPackage : skipPackages) {
14572                    if (skipPackage != null) {
14573                        int NT = receivers.size();
14574                        for (int it=0; it<NT; it++) {
14575                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14576                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14577                                receivers.remove(it);
14578                                it--;
14579                                NT--;
14580                            }
14581                        }
14582                    }
14583                }
14584            }
14585
14586            int NT = receivers != null ? receivers.size() : 0;
14587            int it = 0;
14588            ResolveInfo curt = null;
14589            BroadcastFilter curr = null;
14590            while (it < NT && ir < NR) {
14591                if (curt == null) {
14592                    curt = (ResolveInfo)receivers.get(it);
14593                }
14594                if (curr == null) {
14595                    curr = registeredReceivers.get(ir);
14596                }
14597                if (curr.getPriority() >= curt.priority) {
14598                    // Insert this broadcast record into the final list.
14599                    receivers.add(it, curr);
14600                    ir++;
14601                    curr = null;
14602                    it++;
14603                    NT++;
14604                } else {
14605                    // Skip to the next ResolveInfo in the final list.
14606                    it++;
14607                    curt = null;
14608                }
14609            }
14610        }
14611        while (ir < NR) {
14612            if (receivers == null) {
14613                receivers = new ArrayList();
14614            }
14615            receivers.add(registeredReceivers.get(ir));
14616            ir++;
14617        }
14618
14619        if ((receivers != null && receivers.size() > 0)
14620                || resultTo != null) {
14621            BroadcastQueue queue = broadcastQueueForIntent(intent);
14622            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14623                    callerPackage, callingPid, callingUid, resolvedType,
14624                    requiredPermission, appOp, receivers, resultTo, resultCode,
14625                    resultData, map, ordered, sticky, false, userId);
14626            if (DEBUG_BROADCAST) Slog.v(
14627                    TAG, "Enqueueing ordered broadcast " + r
14628                    + ": prev had " + queue.mOrderedBroadcasts.size());
14629            if (DEBUG_BROADCAST) {
14630                int seq = r.intent.getIntExtra("seq", -1);
14631                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14632            }
14633            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14634            if (!replaced) {
14635                queue.enqueueOrderedBroadcastLocked(r);
14636                queue.scheduleBroadcastsLocked();
14637            }
14638        }
14639
14640        return ActivityManager.BROADCAST_SUCCESS;
14641    }
14642
14643    final Intent verifyBroadcastLocked(Intent intent) {
14644        // Refuse possible leaked file descriptors
14645        if (intent != null && intent.hasFileDescriptors() == true) {
14646            throw new IllegalArgumentException("File descriptors passed in Intent");
14647        }
14648
14649        int flags = intent.getFlags();
14650
14651        if (!mProcessesReady) {
14652            // if the caller really truly claims to know what they're doing, go
14653            // ahead and allow the broadcast without launching any receivers
14654            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14655                intent = new Intent(intent);
14656                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14657            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14658                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14659                        + " before boot completion");
14660                throw new IllegalStateException("Cannot broadcast before boot completed");
14661            }
14662        }
14663
14664        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14665            throw new IllegalArgumentException(
14666                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14667        }
14668
14669        return intent;
14670    }
14671
14672    public final int broadcastIntent(IApplicationThread caller,
14673            Intent intent, String resolvedType, IIntentReceiver resultTo,
14674            int resultCode, String resultData, Bundle map,
14675            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14676        enforceNotIsolatedCaller("broadcastIntent");
14677        synchronized(this) {
14678            intent = verifyBroadcastLocked(intent);
14679
14680            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14681            final int callingPid = Binder.getCallingPid();
14682            final int callingUid = Binder.getCallingUid();
14683            final long origId = Binder.clearCallingIdentity();
14684            int res = broadcastIntentLocked(callerApp,
14685                    callerApp != null ? callerApp.info.packageName : null,
14686                    intent, resolvedType, resultTo,
14687                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14688                    callingPid, callingUid, userId);
14689            Binder.restoreCallingIdentity(origId);
14690            return res;
14691        }
14692    }
14693
14694    int broadcastIntentInPackage(String packageName, int uid,
14695            Intent intent, String resolvedType, IIntentReceiver resultTo,
14696            int resultCode, String resultData, Bundle map,
14697            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14698        synchronized(this) {
14699            intent = verifyBroadcastLocked(intent);
14700
14701            final long origId = Binder.clearCallingIdentity();
14702            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14703                    resultTo, resultCode, resultData, map, requiredPermission,
14704                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14705            Binder.restoreCallingIdentity(origId);
14706            return res;
14707        }
14708    }
14709
14710    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14711        // Refuse possible leaked file descriptors
14712        if (intent != null && intent.hasFileDescriptors() == true) {
14713            throw new IllegalArgumentException("File descriptors passed in Intent");
14714        }
14715
14716        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14717                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14718
14719        synchronized(this) {
14720            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14721                    != PackageManager.PERMISSION_GRANTED) {
14722                String msg = "Permission Denial: unbroadcastIntent() from pid="
14723                        + Binder.getCallingPid()
14724                        + ", uid=" + Binder.getCallingUid()
14725                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14726                Slog.w(TAG, msg);
14727                throw new SecurityException(msg);
14728            }
14729            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14730            if (stickies != null) {
14731                ArrayList<Intent> list = stickies.get(intent.getAction());
14732                if (list != null) {
14733                    int N = list.size();
14734                    int i;
14735                    for (i=0; i<N; i++) {
14736                        if (intent.filterEquals(list.get(i))) {
14737                            list.remove(i);
14738                            break;
14739                        }
14740                    }
14741                    if (list.size() <= 0) {
14742                        stickies.remove(intent.getAction());
14743                    }
14744                }
14745                if (stickies.size() <= 0) {
14746                    mStickyBroadcasts.remove(userId);
14747                }
14748            }
14749        }
14750    }
14751
14752    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14753            String resultData, Bundle resultExtras, boolean resultAbort) {
14754        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14755        if (r == null) {
14756            Slog.w(TAG, "finishReceiver called but not found on queue");
14757            return false;
14758        }
14759
14760        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14761    }
14762
14763    void backgroundServicesFinishedLocked(int userId) {
14764        for (BroadcastQueue queue : mBroadcastQueues) {
14765            queue.backgroundServicesFinishedLocked(userId);
14766        }
14767    }
14768
14769    public void finishReceiver(IBinder who, int resultCode, String resultData,
14770            Bundle resultExtras, boolean resultAbort) {
14771        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14772
14773        // Refuse possible leaked file descriptors
14774        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14775            throw new IllegalArgumentException("File descriptors passed in Bundle");
14776        }
14777
14778        final long origId = Binder.clearCallingIdentity();
14779        try {
14780            boolean doNext = false;
14781            BroadcastRecord r;
14782
14783            synchronized(this) {
14784                r = broadcastRecordForReceiverLocked(who);
14785                if (r != null) {
14786                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14787                        resultData, resultExtras, resultAbort, true);
14788                }
14789            }
14790
14791            if (doNext) {
14792                r.queue.processNextBroadcast(false);
14793            }
14794            trimApplications();
14795        } finally {
14796            Binder.restoreCallingIdentity(origId);
14797        }
14798    }
14799
14800    // =========================================================
14801    // INSTRUMENTATION
14802    // =========================================================
14803
14804    public boolean startInstrumentation(ComponentName className,
14805            String profileFile, int flags, Bundle arguments,
14806            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14807            int userId, String abiOverride) {
14808        enforceNotIsolatedCaller("startInstrumentation");
14809        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14810                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14811        // Refuse possible leaked file descriptors
14812        if (arguments != null && arguments.hasFileDescriptors()) {
14813            throw new IllegalArgumentException("File descriptors passed in Bundle");
14814        }
14815
14816        synchronized(this) {
14817            InstrumentationInfo ii = null;
14818            ApplicationInfo ai = null;
14819            try {
14820                ii = mContext.getPackageManager().getInstrumentationInfo(
14821                    className, STOCK_PM_FLAGS);
14822                ai = AppGlobals.getPackageManager().getApplicationInfo(
14823                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14824            } catch (PackageManager.NameNotFoundException e) {
14825            } catch (RemoteException e) {
14826            }
14827            if (ii == null) {
14828                reportStartInstrumentationFailure(watcher, className,
14829                        "Unable to find instrumentation info for: " + className);
14830                return false;
14831            }
14832            if (ai == null) {
14833                reportStartInstrumentationFailure(watcher, className,
14834                        "Unable to find instrumentation target package: " + ii.targetPackage);
14835                return false;
14836            }
14837
14838            int match = mContext.getPackageManager().checkSignatures(
14839                    ii.targetPackage, ii.packageName);
14840            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14841                String msg = "Permission Denial: starting instrumentation "
14842                        + className + " from pid="
14843                        + Binder.getCallingPid()
14844                        + ", uid=" + Binder.getCallingPid()
14845                        + " not allowed because package " + ii.packageName
14846                        + " does not have a signature matching the target "
14847                        + ii.targetPackage;
14848                reportStartInstrumentationFailure(watcher, className, msg);
14849                throw new SecurityException(msg);
14850            }
14851
14852            final long origId = Binder.clearCallingIdentity();
14853            // Instrumentation can kill and relaunch even persistent processes
14854            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14855                    "start instr");
14856            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14857            app.instrumentationClass = className;
14858            app.instrumentationInfo = ai;
14859            app.instrumentationProfileFile = profileFile;
14860            app.instrumentationArguments = arguments;
14861            app.instrumentationWatcher = watcher;
14862            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14863            app.instrumentationResultClass = className;
14864            Binder.restoreCallingIdentity(origId);
14865        }
14866
14867        return true;
14868    }
14869
14870    /**
14871     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14872     * error to the logs, but if somebody is watching, send the report there too.  This enables
14873     * the "am" command to report errors with more information.
14874     *
14875     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14876     * @param cn The component name of the instrumentation.
14877     * @param report The error report.
14878     */
14879    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14880            ComponentName cn, String report) {
14881        Slog.w(TAG, report);
14882        try {
14883            if (watcher != null) {
14884                Bundle results = new Bundle();
14885                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14886                results.putString("Error", report);
14887                watcher.instrumentationStatus(cn, -1, results);
14888            }
14889        } catch (RemoteException e) {
14890            Slog.w(TAG, e);
14891        }
14892    }
14893
14894    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14895        if (app.instrumentationWatcher != null) {
14896            try {
14897                // NOTE:  IInstrumentationWatcher *must* be oneway here
14898                app.instrumentationWatcher.instrumentationFinished(
14899                    app.instrumentationClass,
14900                    resultCode,
14901                    results);
14902            } catch (RemoteException e) {
14903            }
14904        }
14905        if (app.instrumentationUiAutomationConnection != null) {
14906            try {
14907                app.instrumentationUiAutomationConnection.shutdown();
14908            } catch (RemoteException re) {
14909                /* ignore */
14910            }
14911            // Only a UiAutomation can set this flag and now that
14912            // it is finished we make sure it is reset to its default.
14913            mUserIsMonkey = false;
14914        }
14915        app.instrumentationWatcher = null;
14916        app.instrumentationUiAutomationConnection = null;
14917        app.instrumentationClass = null;
14918        app.instrumentationInfo = null;
14919        app.instrumentationProfileFile = null;
14920        app.instrumentationArguments = null;
14921
14922        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14923                "finished inst");
14924    }
14925
14926    public void finishInstrumentation(IApplicationThread target,
14927            int resultCode, Bundle results) {
14928        int userId = UserHandle.getCallingUserId();
14929        // Refuse possible leaked file descriptors
14930        if (results != null && results.hasFileDescriptors()) {
14931            throw new IllegalArgumentException("File descriptors passed in Intent");
14932        }
14933
14934        synchronized(this) {
14935            ProcessRecord app = getRecordForAppLocked(target);
14936            if (app == null) {
14937                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14938                return;
14939            }
14940            final long origId = Binder.clearCallingIdentity();
14941            finishInstrumentationLocked(app, resultCode, results);
14942            Binder.restoreCallingIdentity(origId);
14943        }
14944    }
14945
14946    // =========================================================
14947    // CONFIGURATION
14948    // =========================================================
14949
14950    public ConfigurationInfo getDeviceConfigurationInfo() {
14951        ConfigurationInfo config = new ConfigurationInfo();
14952        synchronized (this) {
14953            config.reqTouchScreen = mConfiguration.touchscreen;
14954            config.reqKeyboardType = mConfiguration.keyboard;
14955            config.reqNavigation = mConfiguration.navigation;
14956            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14957                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14958                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14959            }
14960            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14961                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14962                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14963            }
14964            config.reqGlEsVersion = GL_ES_VERSION;
14965        }
14966        return config;
14967    }
14968
14969    ActivityStack getFocusedStack() {
14970        return mStackSupervisor.getFocusedStack();
14971    }
14972
14973    public Configuration getConfiguration() {
14974        Configuration ci;
14975        synchronized(this) {
14976            ci = new Configuration(mConfiguration);
14977        }
14978        return ci;
14979    }
14980
14981    public void updatePersistentConfiguration(Configuration values) {
14982        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14983                "updateConfiguration()");
14984        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14985                "updateConfiguration()");
14986        if (values == null) {
14987            throw new NullPointerException("Configuration must not be null");
14988        }
14989
14990        synchronized(this) {
14991            final long origId = Binder.clearCallingIdentity();
14992            updateConfigurationLocked(values, null, true, false);
14993            Binder.restoreCallingIdentity(origId);
14994        }
14995    }
14996
14997    public void updateConfiguration(Configuration values) {
14998        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14999                "updateConfiguration()");
15000
15001        synchronized(this) {
15002            if (values == null && mWindowManager != null) {
15003                // sentinel: fetch the current configuration from the window manager
15004                values = mWindowManager.computeNewConfiguration();
15005            }
15006
15007            if (mWindowManager != null) {
15008                mProcessList.applyDisplaySize(mWindowManager);
15009            }
15010
15011            final long origId = Binder.clearCallingIdentity();
15012            if (values != null) {
15013                Settings.System.clearConfiguration(values);
15014            }
15015            updateConfigurationLocked(values, null, false, false);
15016            Binder.restoreCallingIdentity(origId);
15017        }
15018    }
15019
15020    /**
15021     * Do either or both things: (1) change the current configuration, and (2)
15022     * make sure the given activity is running with the (now) current
15023     * configuration.  Returns true if the activity has been left running, or
15024     * false if <var>starting</var> is being destroyed to match the new
15025     * configuration.
15026     * @param persistent TODO
15027     */
15028    boolean updateConfigurationLocked(Configuration values,
15029            ActivityRecord starting, boolean persistent, boolean initLocale) {
15030        int changes = 0;
15031
15032        if (values != null) {
15033            Configuration newConfig = new Configuration(mConfiguration);
15034            changes = newConfig.updateFrom(values);
15035            if (changes != 0) {
15036                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15037                    Slog.i(TAG, "Updating configuration to: " + values);
15038                }
15039
15040                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15041
15042                if (values.locale != null && !initLocale) {
15043                    saveLocaleLocked(values.locale,
15044                                     !values.locale.equals(mConfiguration.locale),
15045                                     values.userSetLocale);
15046                }
15047
15048                mConfigurationSeq++;
15049                if (mConfigurationSeq <= 0) {
15050                    mConfigurationSeq = 1;
15051                }
15052                newConfig.seq = mConfigurationSeq;
15053                mConfiguration = newConfig;
15054                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15055                //mUsageStatsService.noteStartConfig(newConfig);
15056
15057                final Configuration configCopy = new Configuration(mConfiguration);
15058
15059                // TODO: If our config changes, should we auto dismiss any currently
15060                // showing dialogs?
15061                mShowDialogs = shouldShowDialogs(newConfig);
15062
15063                AttributeCache ac = AttributeCache.instance();
15064                if (ac != null) {
15065                    ac.updateConfiguration(configCopy);
15066                }
15067
15068                // Make sure all resources in our process are updated
15069                // right now, so that anyone who is going to retrieve
15070                // resource values after we return will be sure to get
15071                // the new ones.  This is especially important during
15072                // boot, where the first config change needs to guarantee
15073                // all resources have that config before following boot
15074                // code is executed.
15075                mSystemThread.applyConfigurationToResources(configCopy);
15076
15077                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15078                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15079                    msg.obj = new Configuration(configCopy);
15080                    mHandler.sendMessage(msg);
15081                }
15082
15083                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15084                    ProcessRecord app = mLruProcesses.get(i);
15085                    try {
15086                        if (app.thread != null) {
15087                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15088                                    + app.processName + " new config " + mConfiguration);
15089                            app.thread.scheduleConfigurationChanged(configCopy);
15090                        }
15091                    } catch (Exception e) {
15092                    }
15093                }
15094                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15095                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15096                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15097                        | Intent.FLAG_RECEIVER_FOREGROUND);
15098                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15099                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15100                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15101                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15102                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15103                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15104                    broadcastIntentLocked(null, null, intent,
15105                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15106                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15107                }
15108            }
15109        }
15110
15111        boolean kept = true;
15112        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15113        // mainStack is null during startup.
15114        if (mainStack != null) {
15115            if (changes != 0 && starting == null) {
15116                // If the configuration changed, and the caller is not already
15117                // in the process of starting an activity, then find the top
15118                // activity to check if its configuration needs to change.
15119                starting = mainStack.topRunningActivityLocked(null);
15120            }
15121
15122            if (starting != null) {
15123                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15124                // And we need to make sure at this point that all other activities
15125                // are made visible with the correct configuration.
15126                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15127            }
15128        }
15129
15130        if (values != null && mWindowManager != null) {
15131            mWindowManager.setNewConfiguration(mConfiguration);
15132        }
15133
15134        return kept;
15135    }
15136
15137    /**
15138     * Decide based on the configuration whether we should shouw the ANR,
15139     * crash, etc dialogs.  The idea is that if there is no affordnace to
15140     * press the on-screen buttons, we shouldn't show the dialog.
15141     *
15142     * A thought: SystemUI might also want to get told about this, the Power
15143     * dialog / global actions also might want different behaviors.
15144     */
15145    private static final boolean shouldShowDialogs(Configuration config) {
15146        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15147                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15148    }
15149
15150    /**
15151     * Save the locale.  You must be inside a synchronized (this) block.
15152     */
15153    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15154        if(isDiff) {
15155            SystemProperties.set("user.language", l.getLanguage());
15156            SystemProperties.set("user.region", l.getCountry());
15157        }
15158
15159        if(isPersist) {
15160            SystemProperties.set("persist.sys.language", l.getLanguage());
15161            SystemProperties.set("persist.sys.country", l.getCountry());
15162            SystemProperties.set("persist.sys.localevar", l.getVariant());
15163        }
15164    }
15165
15166    @Override
15167    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15168        ActivityRecord srec = ActivityRecord.forToken(token);
15169        return srec != null && srec.task.affinity != null &&
15170                srec.task.affinity.equals(destAffinity);
15171    }
15172
15173    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15174            Intent resultData) {
15175
15176        synchronized (this) {
15177            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15178            if (stack != null) {
15179                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15180            }
15181            return false;
15182        }
15183    }
15184
15185    public int getLaunchedFromUid(IBinder activityToken) {
15186        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15187        if (srec == null) {
15188            return -1;
15189        }
15190        return srec.launchedFromUid;
15191    }
15192
15193    public String getLaunchedFromPackage(IBinder activityToken) {
15194        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15195        if (srec == null) {
15196            return null;
15197        }
15198        return srec.launchedFromPackage;
15199    }
15200
15201    // =========================================================
15202    // LIFETIME MANAGEMENT
15203    // =========================================================
15204
15205    // Returns which broadcast queue the app is the current [or imminent] receiver
15206    // on, or 'null' if the app is not an active broadcast recipient.
15207    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15208        BroadcastRecord r = app.curReceiver;
15209        if (r != null) {
15210            return r.queue;
15211        }
15212
15213        // It's not the current receiver, but it might be starting up to become one
15214        synchronized (this) {
15215            for (BroadcastQueue queue : mBroadcastQueues) {
15216                r = queue.mPendingBroadcast;
15217                if (r != null && r.curApp == app) {
15218                    // found it; report which queue it's in
15219                    return queue;
15220                }
15221            }
15222        }
15223
15224        return null;
15225    }
15226
15227    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15228            boolean doingAll, long now) {
15229        if (mAdjSeq == app.adjSeq) {
15230            // This adjustment has already been computed.
15231            return app.curRawAdj;
15232        }
15233
15234        if (app.thread == null) {
15235            app.adjSeq = mAdjSeq;
15236            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15237            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15238            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15239        }
15240
15241        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15242        app.adjSource = null;
15243        app.adjTarget = null;
15244        app.empty = false;
15245        app.cached = false;
15246
15247        final int activitiesSize = app.activities.size();
15248
15249        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15250            // The max adjustment doesn't allow this app to be anything
15251            // below foreground, so it is not worth doing work for it.
15252            app.adjType = "fixed";
15253            app.adjSeq = mAdjSeq;
15254            app.curRawAdj = app.maxAdj;
15255            app.foregroundActivities = false;
15256            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15257            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15258            // System processes can do UI, and when they do we want to have
15259            // them trim their memory after the user leaves the UI.  To
15260            // facilitate this, here we need to determine whether or not it
15261            // is currently showing UI.
15262            app.systemNoUi = true;
15263            if (app == TOP_APP) {
15264                app.systemNoUi = false;
15265            } else if (activitiesSize > 0) {
15266                for (int j = 0; j < activitiesSize; j++) {
15267                    final ActivityRecord r = app.activities.get(j);
15268                    if (r.visible) {
15269                        app.systemNoUi = false;
15270                    }
15271                }
15272            }
15273            if (!app.systemNoUi) {
15274                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15275            }
15276            return (app.curAdj=app.maxAdj);
15277        }
15278
15279        app.systemNoUi = false;
15280
15281        // Determine the importance of the process, starting with most
15282        // important to least, and assign an appropriate OOM adjustment.
15283        int adj;
15284        int schedGroup;
15285        int procState;
15286        boolean foregroundActivities = false;
15287        BroadcastQueue queue;
15288        if (app == TOP_APP) {
15289            // The last app on the list is the foreground app.
15290            adj = ProcessList.FOREGROUND_APP_ADJ;
15291            schedGroup = Process.THREAD_GROUP_DEFAULT;
15292            app.adjType = "top-activity";
15293            foregroundActivities = true;
15294            procState = ActivityManager.PROCESS_STATE_TOP;
15295        } else if (app.instrumentationClass != null) {
15296            // Don't want to kill running instrumentation.
15297            adj = ProcessList.FOREGROUND_APP_ADJ;
15298            schedGroup = Process.THREAD_GROUP_DEFAULT;
15299            app.adjType = "instrumentation";
15300            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15301        } else if ((queue = isReceivingBroadcast(app)) != null) {
15302            // An app that is currently receiving a broadcast also
15303            // counts as being in the foreground for OOM killer purposes.
15304            // It's placed in a sched group based on the nature of the
15305            // broadcast as reflected by which queue it's active in.
15306            adj = ProcessList.FOREGROUND_APP_ADJ;
15307            schedGroup = (queue == mFgBroadcastQueue)
15308                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15309            app.adjType = "broadcast";
15310            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15311        } else if (app.executingServices.size() > 0) {
15312            // An app that is currently executing a service callback also
15313            // counts as being in the foreground.
15314            adj = ProcessList.FOREGROUND_APP_ADJ;
15315            schedGroup = app.execServicesFg ?
15316                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15317            app.adjType = "exec-service";
15318            procState = ActivityManager.PROCESS_STATE_SERVICE;
15319            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15320        } else {
15321            // As far as we know the process is empty.  We may change our mind later.
15322            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15323            // At this point we don't actually know the adjustment.  Use the cached adj
15324            // value that the caller wants us to.
15325            adj = cachedAdj;
15326            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15327            app.cached = true;
15328            app.empty = true;
15329            app.adjType = "cch-empty";
15330        }
15331
15332        // Examine all activities if not already foreground.
15333        if (!foregroundActivities && activitiesSize > 0) {
15334            for (int j = 0; j < activitiesSize; j++) {
15335                final ActivityRecord r = app.activities.get(j);
15336                if (r.app != app) {
15337                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15338                            + app + "?!?");
15339                    continue;
15340                }
15341                if (r.visible) {
15342                    // App has a visible activity; only upgrade adjustment.
15343                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15344                        adj = ProcessList.VISIBLE_APP_ADJ;
15345                        app.adjType = "visible";
15346                    }
15347                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15348                        procState = ActivityManager.PROCESS_STATE_TOP;
15349                    }
15350                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15351                    app.cached = false;
15352                    app.empty = false;
15353                    foregroundActivities = true;
15354                    break;
15355                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15356                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15357                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15358                        app.adjType = "pausing";
15359                    }
15360                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15361                        procState = ActivityManager.PROCESS_STATE_TOP;
15362                    }
15363                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15364                    app.cached = false;
15365                    app.empty = false;
15366                    foregroundActivities = true;
15367                } else if (r.state == ActivityState.STOPPING) {
15368                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15369                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15370                        app.adjType = "stopping";
15371                    }
15372                    // For the process state, we will at this point consider the
15373                    // process to be cached.  It will be cached either as an activity
15374                    // or empty depending on whether the activity is finishing.  We do
15375                    // this so that we can treat the process as cached for purposes of
15376                    // memory trimming (determing current memory level, trim command to
15377                    // send to process) since there can be an arbitrary number of stopping
15378                    // processes and they should soon all go into the cached state.
15379                    if (!r.finishing) {
15380                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15381                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15382                        }
15383                    }
15384                    app.cached = false;
15385                    app.empty = false;
15386                    foregroundActivities = true;
15387                } else {
15388                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15389                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15390                        app.adjType = "cch-act";
15391                    }
15392                }
15393            }
15394        }
15395
15396        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15397            if (app.foregroundServices) {
15398                // The user is aware of this app, so make it visible.
15399                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15400                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15401                app.cached = false;
15402                app.adjType = "fg-service";
15403                schedGroup = Process.THREAD_GROUP_DEFAULT;
15404            } else if (app.forcingToForeground != null) {
15405                // The user is aware of this app, so make it visible.
15406                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15407                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15408                app.cached = false;
15409                app.adjType = "force-fg";
15410                app.adjSource = app.forcingToForeground;
15411                schedGroup = Process.THREAD_GROUP_DEFAULT;
15412            }
15413        }
15414
15415        if (app == mHeavyWeightProcess) {
15416            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15417                // We don't want to kill the current heavy-weight process.
15418                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15419                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15420                app.cached = false;
15421                app.adjType = "heavy";
15422            }
15423            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15424                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15425            }
15426        }
15427
15428        if (app == mHomeProcess) {
15429            if (adj > ProcessList.HOME_APP_ADJ) {
15430                // This process is hosting what we currently consider to be the
15431                // home app, so we don't want to let it go into the background.
15432                adj = ProcessList.HOME_APP_ADJ;
15433                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15434                app.cached = false;
15435                app.adjType = "home";
15436            }
15437            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15438                procState = ActivityManager.PROCESS_STATE_HOME;
15439            }
15440        }
15441
15442        if (app == mPreviousProcess && app.activities.size() > 0) {
15443            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15444                // This was the previous process that showed UI to the user.
15445                // We want to try to keep it around more aggressively, to give
15446                // a good experience around switching between two apps.
15447                adj = ProcessList.PREVIOUS_APP_ADJ;
15448                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15449                app.cached = false;
15450                app.adjType = "previous";
15451            }
15452            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15453                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15454            }
15455        }
15456
15457        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15458                + " reason=" + app.adjType);
15459
15460        // By default, we use the computed adjustment.  It may be changed if
15461        // there are applications dependent on our services or providers, but
15462        // this gives us a baseline and makes sure we don't get into an
15463        // infinite recursion.
15464        app.adjSeq = mAdjSeq;
15465        app.curRawAdj = adj;
15466        app.hasStartedServices = false;
15467
15468        if (mBackupTarget != null && app == mBackupTarget.app) {
15469            // If possible we want to avoid killing apps while they're being backed up
15470            if (adj > ProcessList.BACKUP_APP_ADJ) {
15471                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15472                adj = ProcessList.BACKUP_APP_ADJ;
15473                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15474                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15475                }
15476                app.adjType = "backup";
15477                app.cached = false;
15478            }
15479            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15480                procState = ActivityManager.PROCESS_STATE_BACKUP;
15481            }
15482        }
15483
15484        boolean mayBeTop = false;
15485
15486        for (int is = app.services.size()-1;
15487                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15488                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15489                        || procState > ActivityManager.PROCESS_STATE_TOP);
15490                is--) {
15491            ServiceRecord s = app.services.valueAt(is);
15492            if (s.startRequested) {
15493                app.hasStartedServices = true;
15494                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15495                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15496                }
15497                if (app.hasShownUi && app != mHomeProcess) {
15498                    // If this process has shown some UI, let it immediately
15499                    // go to the LRU list because it may be pretty heavy with
15500                    // UI stuff.  We'll tag it with a label just to help
15501                    // debug and understand what is going on.
15502                    if (adj > ProcessList.SERVICE_ADJ) {
15503                        app.adjType = "cch-started-ui-services";
15504                    }
15505                } else {
15506                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15507                        // This service has seen some activity within
15508                        // recent memory, so we will keep its process ahead
15509                        // of the background processes.
15510                        if (adj > ProcessList.SERVICE_ADJ) {
15511                            adj = ProcessList.SERVICE_ADJ;
15512                            app.adjType = "started-services";
15513                            app.cached = false;
15514                        }
15515                    }
15516                    // If we have let the service slide into the background
15517                    // state, still have some text describing what it is doing
15518                    // even though the service no longer has an impact.
15519                    if (adj > ProcessList.SERVICE_ADJ) {
15520                        app.adjType = "cch-started-services";
15521                    }
15522                }
15523            }
15524            for (int conni = s.connections.size()-1;
15525                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15526                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15527                            || procState > ActivityManager.PROCESS_STATE_TOP);
15528                    conni--) {
15529                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15530                for (int i = 0;
15531                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15532                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15533                                || procState > ActivityManager.PROCESS_STATE_TOP);
15534                        i++) {
15535                    // XXX should compute this based on the max of
15536                    // all connected clients.
15537                    ConnectionRecord cr = clist.get(i);
15538                    if (cr.binding.client == app) {
15539                        // Binding to ourself is not interesting.
15540                        continue;
15541                    }
15542                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15543                        ProcessRecord client = cr.binding.client;
15544                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15545                                TOP_APP, doingAll, now);
15546                        int clientProcState = client.curProcState;
15547                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15548                            // If the other app is cached for any reason, for purposes here
15549                            // we are going to consider it empty.  The specific cached state
15550                            // doesn't propagate except under certain conditions.
15551                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15552                        }
15553                        String adjType = null;
15554                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15555                            // Not doing bind OOM management, so treat
15556                            // this guy more like a started service.
15557                            if (app.hasShownUi && app != mHomeProcess) {
15558                                // If this process has shown some UI, let it immediately
15559                                // go to the LRU list because it may be pretty heavy with
15560                                // UI stuff.  We'll tag it with a label just to help
15561                                // debug and understand what is going on.
15562                                if (adj > clientAdj) {
15563                                    adjType = "cch-bound-ui-services";
15564                                }
15565                                app.cached = false;
15566                                clientAdj = adj;
15567                                clientProcState = procState;
15568                            } else {
15569                                if (now >= (s.lastActivity
15570                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15571                                    // This service has not seen activity within
15572                                    // recent memory, so allow it to drop to the
15573                                    // LRU list if there is no other reason to keep
15574                                    // it around.  We'll also tag it with a label just
15575                                    // to help debug and undertand what is going on.
15576                                    if (adj > clientAdj) {
15577                                        adjType = "cch-bound-services";
15578                                    }
15579                                    clientAdj = adj;
15580                                }
15581                            }
15582                        }
15583                        if (adj > clientAdj) {
15584                            // If this process has recently shown UI, and
15585                            // the process that is binding to it is less
15586                            // important than being visible, then we don't
15587                            // care about the binding as much as we care
15588                            // about letting this process get into the LRU
15589                            // list to be killed and restarted if needed for
15590                            // memory.
15591                            if (app.hasShownUi && app != mHomeProcess
15592                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15593                                adjType = "cch-bound-ui-services";
15594                            } else {
15595                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15596                                        |Context.BIND_IMPORTANT)) != 0) {
15597                                    adj = clientAdj;
15598                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15599                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15600                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15601                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15602                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15603                                    adj = clientAdj;
15604                                } else {
15605                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15606                                        adj = ProcessList.VISIBLE_APP_ADJ;
15607                                    }
15608                                }
15609                                if (!client.cached) {
15610                                    app.cached = false;
15611                                }
15612                                adjType = "service";
15613                            }
15614                        }
15615                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15616                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15617                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15618                            }
15619                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15620                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15621                                    // Special handling of clients who are in the top state.
15622                                    // We *may* want to consider this process to be in the
15623                                    // top state as well, but only if there is not another
15624                                    // reason for it to be running.  Being on the top is a
15625                                    // special state, meaning you are specifically running
15626                                    // for the current top app.  If the process is already
15627                                    // running in the background for some other reason, it
15628                                    // is more important to continue considering it to be
15629                                    // in the background state.
15630                                    mayBeTop = true;
15631                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15632                                } else {
15633                                    // Special handling for above-top states (persistent
15634                                    // processes).  These should not bring the current process
15635                                    // into the top state, since they are not on top.  Instead
15636                                    // give them the best state after that.
15637                                    clientProcState =
15638                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15639                                }
15640                            }
15641                        } else {
15642                            if (clientProcState <
15643                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15644                                clientProcState =
15645                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15646                            }
15647                        }
15648                        if (procState > clientProcState) {
15649                            procState = clientProcState;
15650                        }
15651                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15652                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15653                            app.pendingUiClean = true;
15654                        }
15655                        if (adjType != null) {
15656                            app.adjType = adjType;
15657                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15658                                    .REASON_SERVICE_IN_USE;
15659                            app.adjSource = cr.binding.client;
15660                            app.adjSourceProcState = clientProcState;
15661                            app.adjTarget = s.name;
15662                        }
15663                    }
15664                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15665                        app.treatLikeActivity = true;
15666                    }
15667                    final ActivityRecord a = cr.activity;
15668                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15669                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15670                                (a.visible || a.state == ActivityState.RESUMED
15671                                 || a.state == ActivityState.PAUSING)) {
15672                            adj = ProcessList.FOREGROUND_APP_ADJ;
15673                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15674                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15675                            }
15676                            app.cached = false;
15677                            app.adjType = "service";
15678                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15679                                    .REASON_SERVICE_IN_USE;
15680                            app.adjSource = a;
15681                            app.adjSourceProcState = procState;
15682                            app.adjTarget = s.name;
15683                        }
15684                    }
15685                }
15686            }
15687        }
15688
15689        for (int provi = app.pubProviders.size()-1;
15690                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15691                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15692                        || procState > ActivityManager.PROCESS_STATE_TOP);
15693                provi--) {
15694            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15695            for (int i = cpr.connections.size()-1;
15696                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15697                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15698                            || procState > ActivityManager.PROCESS_STATE_TOP);
15699                    i--) {
15700                ContentProviderConnection conn = cpr.connections.get(i);
15701                ProcessRecord client = conn.client;
15702                if (client == app) {
15703                    // Being our own client is not interesting.
15704                    continue;
15705                }
15706                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15707                int clientProcState = client.curProcState;
15708                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15709                    // If the other app is cached for any reason, for purposes here
15710                    // we are going to consider it empty.
15711                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15712                }
15713                if (adj > clientAdj) {
15714                    if (app.hasShownUi && app != mHomeProcess
15715                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15716                        app.adjType = "cch-ui-provider";
15717                    } else {
15718                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15719                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15720                        app.adjType = "provider";
15721                    }
15722                    app.cached &= client.cached;
15723                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15724                            .REASON_PROVIDER_IN_USE;
15725                    app.adjSource = client;
15726                    app.adjSourceProcState = clientProcState;
15727                    app.adjTarget = cpr.name;
15728                }
15729                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15730                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15731                        // Special handling of clients who are in the top state.
15732                        // We *may* want to consider this process to be in the
15733                        // top state as well, but only if there is not another
15734                        // reason for it to be running.  Being on the top is a
15735                        // special state, meaning you are specifically running
15736                        // for the current top app.  If the process is already
15737                        // running in the background for some other reason, it
15738                        // is more important to continue considering it to be
15739                        // in the background state.
15740                        mayBeTop = true;
15741                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15742                    } else {
15743                        // Special handling for above-top states (persistent
15744                        // processes).  These should not bring the current process
15745                        // into the top state, since they are not on top.  Instead
15746                        // give them the best state after that.
15747                        clientProcState =
15748                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15749                    }
15750                }
15751                if (procState > clientProcState) {
15752                    procState = clientProcState;
15753                }
15754                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15755                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15756                }
15757            }
15758            // If the provider has external (non-framework) process
15759            // dependencies, ensure that its adjustment is at least
15760            // FOREGROUND_APP_ADJ.
15761            if (cpr.hasExternalProcessHandles()) {
15762                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15763                    adj = ProcessList.FOREGROUND_APP_ADJ;
15764                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15765                    app.cached = false;
15766                    app.adjType = "provider";
15767                    app.adjTarget = cpr.name;
15768                }
15769                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15770                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15771                }
15772            }
15773        }
15774
15775        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15776            // A client of one of our services or providers is in the top state.  We
15777            // *may* want to be in the top state, but not if we are already running in
15778            // the background for some other reason.  For the decision here, we are going
15779            // to pick out a few specific states that we want to remain in when a client
15780            // is top (states that tend to be longer-term) and otherwise allow it to go
15781            // to the top state.
15782            switch (procState) {
15783                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15784                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15785                case ActivityManager.PROCESS_STATE_SERVICE:
15786                    // These all are longer-term states, so pull them up to the top
15787                    // of the background states, but not all the way to the top state.
15788                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15789                    break;
15790                default:
15791                    // Otherwise, top is a better choice, so take it.
15792                    procState = ActivityManager.PROCESS_STATE_TOP;
15793                    break;
15794            }
15795        }
15796
15797        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15798            if (app.hasClientActivities) {
15799                // This is a cached process, but with client activities.  Mark it so.
15800                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15801                app.adjType = "cch-client-act";
15802            } else if (app.treatLikeActivity) {
15803                // This is a cached process, but somebody wants us to treat it like it has
15804                // an activity, okay!
15805                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15806                app.adjType = "cch-as-act";
15807            }
15808        }
15809
15810        if (adj == ProcessList.SERVICE_ADJ) {
15811            if (doingAll) {
15812                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15813                mNewNumServiceProcs++;
15814                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15815                if (!app.serviceb) {
15816                    // This service isn't far enough down on the LRU list to
15817                    // normally be a B service, but if we are low on RAM and it
15818                    // is large we want to force it down since we would prefer to
15819                    // keep launcher over it.
15820                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15821                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15822                        app.serviceHighRam = true;
15823                        app.serviceb = true;
15824                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15825                    } else {
15826                        mNewNumAServiceProcs++;
15827                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15828                    }
15829                } else {
15830                    app.serviceHighRam = false;
15831                }
15832            }
15833            if (app.serviceb) {
15834                adj = ProcessList.SERVICE_B_ADJ;
15835            }
15836        }
15837
15838        app.curRawAdj = adj;
15839
15840        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15841        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15842        if (adj > app.maxAdj) {
15843            adj = app.maxAdj;
15844            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15845                schedGroup = Process.THREAD_GROUP_DEFAULT;
15846            }
15847        }
15848
15849        // Do final modification to adj.  Everything we do between here and applying
15850        // the final setAdj must be done in this function, because we will also use
15851        // it when computing the final cached adj later.  Note that we don't need to
15852        // worry about this for max adj above, since max adj will always be used to
15853        // keep it out of the cached vaues.
15854        app.curAdj = app.modifyRawOomAdj(adj);
15855        app.curSchedGroup = schedGroup;
15856        app.curProcState = procState;
15857        app.foregroundActivities = foregroundActivities;
15858
15859        return app.curRawAdj;
15860    }
15861
15862    /**
15863     * Schedule PSS collection of a process.
15864     */
15865    void requestPssLocked(ProcessRecord proc, int procState) {
15866        if (mPendingPssProcesses.contains(proc)) {
15867            return;
15868        }
15869        if (mPendingPssProcesses.size() == 0) {
15870            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15871        }
15872        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15873        proc.pssProcState = procState;
15874        mPendingPssProcesses.add(proc);
15875    }
15876
15877    /**
15878     * Schedule PSS collection of all processes.
15879     */
15880    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15881        if (!always) {
15882            if (now < (mLastFullPssTime +
15883                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15884                return;
15885            }
15886        }
15887        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15888        mLastFullPssTime = now;
15889        mFullPssPending = true;
15890        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15891        mPendingPssProcesses.clear();
15892        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15893            ProcessRecord app = mLruProcesses.get(i);
15894            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15895                app.pssProcState = app.setProcState;
15896                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15897                        isSleeping(), now);
15898                mPendingPssProcesses.add(app);
15899            }
15900        }
15901        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15902    }
15903
15904    /**
15905     * Ask a given process to GC right now.
15906     */
15907    final void performAppGcLocked(ProcessRecord app) {
15908        try {
15909            app.lastRequestedGc = SystemClock.uptimeMillis();
15910            if (app.thread != null) {
15911                if (app.reportLowMemory) {
15912                    app.reportLowMemory = false;
15913                    app.thread.scheduleLowMemory();
15914                } else {
15915                    app.thread.processInBackground();
15916                }
15917            }
15918        } catch (Exception e) {
15919            // whatever.
15920        }
15921    }
15922
15923    /**
15924     * Returns true if things are idle enough to perform GCs.
15925     */
15926    private final boolean canGcNowLocked() {
15927        boolean processingBroadcasts = false;
15928        for (BroadcastQueue q : mBroadcastQueues) {
15929            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15930                processingBroadcasts = true;
15931            }
15932        }
15933        return !processingBroadcasts
15934                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15935    }
15936
15937    /**
15938     * Perform GCs on all processes that are waiting for it, but only
15939     * if things are idle.
15940     */
15941    final void performAppGcsLocked() {
15942        final int N = mProcessesToGc.size();
15943        if (N <= 0) {
15944            return;
15945        }
15946        if (canGcNowLocked()) {
15947            while (mProcessesToGc.size() > 0) {
15948                ProcessRecord proc = mProcessesToGc.remove(0);
15949                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15950                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15951                            <= SystemClock.uptimeMillis()) {
15952                        // To avoid spamming the system, we will GC processes one
15953                        // at a time, waiting a few seconds between each.
15954                        performAppGcLocked(proc);
15955                        scheduleAppGcsLocked();
15956                        return;
15957                    } else {
15958                        // It hasn't been long enough since we last GCed this
15959                        // process...  put it in the list to wait for its time.
15960                        addProcessToGcListLocked(proc);
15961                        break;
15962                    }
15963                }
15964            }
15965
15966            scheduleAppGcsLocked();
15967        }
15968    }
15969
15970    /**
15971     * If all looks good, perform GCs on all processes waiting for them.
15972     */
15973    final void performAppGcsIfAppropriateLocked() {
15974        if (canGcNowLocked()) {
15975            performAppGcsLocked();
15976            return;
15977        }
15978        // Still not idle, wait some more.
15979        scheduleAppGcsLocked();
15980    }
15981
15982    /**
15983     * Schedule the execution of all pending app GCs.
15984     */
15985    final void scheduleAppGcsLocked() {
15986        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15987
15988        if (mProcessesToGc.size() > 0) {
15989            // Schedule a GC for the time to the next process.
15990            ProcessRecord proc = mProcessesToGc.get(0);
15991            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15992
15993            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15994            long now = SystemClock.uptimeMillis();
15995            if (when < (now+GC_TIMEOUT)) {
15996                when = now + GC_TIMEOUT;
15997            }
15998            mHandler.sendMessageAtTime(msg, when);
15999        }
16000    }
16001
16002    /**
16003     * Add a process to the array of processes waiting to be GCed.  Keeps the
16004     * list in sorted order by the last GC time.  The process can't already be
16005     * on the list.
16006     */
16007    final void addProcessToGcListLocked(ProcessRecord proc) {
16008        boolean added = false;
16009        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16010            if (mProcessesToGc.get(i).lastRequestedGc <
16011                    proc.lastRequestedGc) {
16012                added = true;
16013                mProcessesToGc.add(i+1, proc);
16014                break;
16015            }
16016        }
16017        if (!added) {
16018            mProcessesToGc.add(0, proc);
16019        }
16020    }
16021
16022    /**
16023     * Set up to ask a process to GC itself.  This will either do it
16024     * immediately, or put it on the list of processes to gc the next
16025     * time things are idle.
16026     */
16027    final void scheduleAppGcLocked(ProcessRecord app) {
16028        long now = SystemClock.uptimeMillis();
16029        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16030            return;
16031        }
16032        if (!mProcessesToGc.contains(app)) {
16033            addProcessToGcListLocked(app);
16034            scheduleAppGcsLocked();
16035        }
16036    }
16037
16038    final void checkExcessivePowerUsageLocked(boolean doKills) {
16039        updateCpuStatsNow();
16040
16041        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16042        boolean doWakeKills = doKills;
16043        boolean doCpuKills = doKills;
16044        if (mLastPowerCheckRealtime == 0) {
16045            doWakeKills = false;
16046        }
16047        if (mLastPowerCheckUptime == 0) {
16048            doCpuKills = false;
16049        }
16050        if (stats.isScreenOn()) {
16051            doWakeKills = false;
16052        }
16053        final long curRealtime = SystemClock.elapsedRealtime();
16054        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16055        final long curUptime = SystemClock.uptimeMillis();
16056        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16057        mLastPowerCheckRealtime = curRealtime;
16058        mLastPowerCheckUptime = curUptime;
16059        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16060            doWakeKills = false;
16061        }
16062        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16063            doCpuKills = false;
16064        }
16065        int i = mLruProcesses.size();
16066        while (i > 0) {
16067            i--;
16068            ProcessRecord app = mLruProcesses.get(i);
16069            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16070                long wtime;
16071                synchronized (stats) {
16072                    wtime = stats.getProcessWakeTime(app.info.uid,
16073                            app.pid, curRealtime);
16074                }
16075                long wtimeUsed = wtime - app.lastWakeTime;
16076                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16077                if (DEBUG_POWER) {
16078                    StringBuilder sb = new StringBuilder(128);
16079                    sb.append("Wake for ");
16080                    app.toShortString(sb);
16081                    sb.append(": over ");
16082                    TimeUtils.formatDuration(realtimeSince, sb);
16083                    sb.append(" used ");
16084                    TimeUtils.formatDuration(wtimeUsed, sb);
16085                    sb.append(" (");
16086                    sb.append((wtimeUsed*100)/realtimeSince);
16087                    sb.append("%)");
16088                    Slog.i(TAG, sb.toString());
16089                    sb.setLength(0);
16090                    sb.append("CPU for ");
16091                    app.toShortString(sb);
16092                    sb.append(": over ");
16093                    TimeUtils.formatDuration(uptimeSince, sb);
16094                    sb.append(" used ");
16095                    TimeUtils.formatDuration(cputimeUsed, sb);
16096                    sb.append(" (");
16097                    sb.append((cputimeUsed*100)/uptimeSince);
16098                    sb.append("%)");
16099                    Slog.i(TAG, sb.toString());
16100                }
16101                // If a process has held a wake lock for more
16102                // than 50% of the time during this period,
16103                // that sounds bad.  Kill!
16104                if (doWakeKills && realtimeSince > 0
16105                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16106                    synchronized (stats) {
16107                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16108                                realtimeSince, wtimeUsed);
16109                    }
16110                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16111                            + " during " + realtimeSince);
16112                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16113                } else if (doCpuKills && uptimeSince > 0
16114                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16115                    synchronized (stats) {
16116                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16117                                uptimeSince, cputimeUsed);
16118                    }
16119                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16120                            + " during " + uptimeSince);
16121                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16122                } else {
16123                    app.lastWakeTime = wtime;
16124                    app.lastCpuTime = app.curCpuTime;
16125                }
16126            }
16127        }
16128    }
16129
16130    private final boolean applyOomAdjLocked(ProcessRecord app,
16131            ProcessRecord TOP_APP, boolean doingAll, long now) {
16132        boolean success = true;
16133
16134        if (app.curRawAdj != app.setRawAdj) {
16135            app.setRawAdj = app.curRawAdj;
16136        }
16137
16138        int changes = 0;
16139
16140        if (app.curAdj != app.setAdj) {
16141            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16142            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16143                TAG, "Set " + app.pid + " " + app.processName +
16144                " adj " + app.curAdj + ": " + app.adjType);
16145            app.setAdj = app.curAdj;
16146        }
16147
16148        if (app.setSchedGroup != app.curSchedGroup) {
16149            app.setSchedGroup = app.curSchedGroup;
16150            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16151                    "Setting process group of " + app.processName
16152                    + " to " + app.curSchedGroup);
16153            if (app.waitingToKill != null &&
16154                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16155                killUnneededProcessLocked(app, app.waitingToKill);
16156                success = false;
16157            } else {
16158                if (true) {
16159                    long oldId = Binder.clearCallingIdentity();
16160                    try {
16161                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16162                    } catch (Exception e) {
16163                        Slog.w(TAG, "Failed setting process group of " + app.pid
16164                                + " to " + app.curSchedGroup);
16165                        e.printStackTrace();
16166                    } finally {
16167                        Binder.restoreCallingIdentity(oldId);
16168                    }
16169                } else {
16170                    if (app.thread != null) {
16171                        try {
16172                            app.thread.setSchedulingGroup(app.curSchedGroup);
16173                        } catch (RemoteException e) {
16174                        }
16175                    }
16176                }
16177                Process.setSwappiness(app.pid,
16178                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16179            }
16180        }
16181        if (app.repForegroundActivities != app.foregroundActivities) {
16182            app.repForegroundActivities = app.foregroundActivities;
16183            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16184        }
16185        if (app.repProcState != app.curProcState) {
16186            app.repProcState = app.curProcState;
16187            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16188            if (app.thread != null) {
16189                try {
16190                    if (false) {
16191                        //RuntimeException h = new RuntimeException("here");
16192                        Slog.i(TAG, "Sending new process state " + app.repProcState
16193                                + " to " + app /*, h*/);
16194                    }
16195                    app.thread.setProcessState(app.repProcState);
16196                } catch (RemoteException e) {
16197                }
16198            }
16199        }
16200        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16201                app.setProcState)) {
16202            app.lastStateTime = now;
16203            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16204                    isSleeping(), now);
16205            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16206                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16207                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16208                    + (app.nextPssTime-now) + ": " + app);
16209        } else {
16210            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16211                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16212                requestPssLocked(app, app.setProcState);
16213                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16214                        isSleeping(), now);
16215            } else if (false && DEBUG_PSS) {
16216                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16217            }
16218        }
16219        if (app.setProcState != app.curProcState) {
16220            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16221                    "Proc state change of " + app.processName
16222                    + " to " + app.curProcState);
16223            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16224            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16225            if (setImportant && !curImportant) {
16226                // This app is no longer something we consider important enough to allow to
16227                // use arbitrary amounts of battery power.  Note
16228                // its current wake lock time to later know to kill it if
16229                // it is not behaving well.
16230                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16231                synchronized (stats) {
16232                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16233                            app.pid, SystemClock.elapsedRealtime());
16234                }
16235                app.lastCpuTime = app.curCpuTime;
16236
16237            }
16238            app.setProcState = app.curProcState;
16239            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16240                app.notCachedSinceIdle = false;
16241            }
16242            if (!doingAll) {
16243                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16244            } else {
16245                app.procStateChanged = true;
16246            }
16247        }
16248
16249        if (changes != 0) {
16250            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16251            int i = mPendingProcessChanges.size()-1;
16252            ProcessChangeItem item = null;
16253            while (i >= 0) {
16254                item = mPendingProcessChanges.get(i);
16255                if (item.pid == app.pid) {
16256                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16257                    break;
16258                }
16259                i--;
16260            }
16261            if (i < 0) {
16262                // No existing item in pending changes; need a new one.
16263                final int NA = mAvailProcessChanges.size();
16264                if (NA > 0) {
16265                    item = mAvailProcessChanges.remove(NA-1);
16266                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16267                } else {
16268                    item = new ProcessChangeItem();
16269                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16270                }
16271                item.changes = 0;
16272                item.pid = app.pid;
16273                item.uid = app.info.uid;
16274                if (mPendingProcessChanges.size() == 0) {
16275                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16276                            "*** Enqueueing dispatch processes changed!");
16277                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16278                }
16279                mPendingProcessChanges.add(item);
16280            }
16281            item.changes |= changes;
16282            item.processState = app.repProcState;
16283            item.foregroundActivities = app.repForegroundActivities;
16284            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16285                    + Integer.toHexString(System.identityHashCode(item))
16286                    + " " + app.toShortString() + ": changes=" + item.changes
16287                    + " procState=" + item.processState
16288                    + " foreground=" + item.foregroundActivities
16289                    + " type=" + app.adjType + " source=" + app.adjSource
16290                    + " target=" + app.adjTarget);
16291        }
16292
16293        return success;
16294    }
16295
16296    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16297        if (proc.thread != null) {
16298            if (proc.baseProcessTracker != null) {
16299                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16300            }
16301            if (proc.repProcState >= 0) {
16302                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16303                        proc.repProcState);
16304            }
16305        }
16306    }
16307
16308    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16309            ProcessRecord TOP_APP, boolean doingAll, long now) {
16310        if (app.thread == null) {
16311            return false;
16312        }
16313
16314        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16315
16316        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16317    }
16318
16319    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16320            boolean oomAdj) {
16321        if (isForeground != proc.foregroundServices) {
16322            proc.foregroundServices = isForeground;
16323            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16324                    proc.info.uid);
16325            if (isForeground) {
16326                if (curProcs == null) {
16327                    curProcs = new ArrayList<ProcessRecord>();
16328                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16329                }
16330                if (!curProcs.contains(proc)) {
16331                    curProcs.add(proc);
16332                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16333                            proc.info.packageName, proc.info.uid);
16334                }
16335            } else {
16336                if (curProcs != null) {
16337                    if (curProcs.remove(proc)) {
16338                        mBatteryStatsService.noteEvent(
16339                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16340                                proc.info.packageName, proc.info.uid);
16341                        if (curProcs.size() <= 0) {
16342                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16343                        }
16344                    }
16345                }
16346            }
16347            if (oomAdj) {
16348                updateOomAdjLocked();
16349            }
16350        }
16351    }
16352
16353    private final ActivityRecord resumedAppLocked() {
16354        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16355        String pkg;
16356        int uid;
16357        if (act != null) {
16358            pkg = act.packageName;
16359            uid = act.info.applicationInfo.uid;
16360        } else {
16361            pkg = null;
16362            uid = -1;
16363        }
16364        // Has the UID or resumed package name changed?
16365        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16366                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16367            if (mCurResumedPackage != null) {
16368                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16369                        mCurResumedPackage, mCurResumedUid);
16370            }
16371            mCurResumedPackage = pkg;
16372            mCurResumedUid = uid;
16373            if (mCurResumedPackage != null) {
16374                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16375                        mCurResumedPackage, mCurResumedUid);
16376            }
16377        }
16378        return act;
16379    }
16380
16381    final boolean updateOomAdjLocked(ProcessRecord app) {
16382        final ActivityRecord TOP_ACT = resumedAppLocked();
16383        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16384        final boolean wasCached = app.cached;
16385
16386        mAdjSeq++;
16387
16388        // This is the desired cached adjusment we want to tell it to use.
16389        // If our app is currently cached, we know it, and that is it.  Otherwise,
16390        // we don't know it yet, and it needs to now be cached we will then
16391        // need to do a complete oom adj.
16392        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16393                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16394        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16395                SystemClock.uptimeMillis());
16396        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16397            // Changed to/from cached state, so apps after it in the LRU
16398            // list may also be changed.
16399            updateOomAdjLocked();
16400        }
16401        return success;
16402    }
16403
16404    final void updateOomAdjLocked() {
16405        final ActivityRecord TOP_ACT = resumedAppLocked();
16406        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16407        final long now = SystemClock.uptimeMillis();
16408        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16409        final int N = mLruProcesses.size();
16410
16411        if (false) {
16412            RuntimeException e = new RuntimeException();
16413            e.fillInStackTrace();
16414            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16415        }
16416
16417        mAdjSeq++;
16418        mNewNumServiceProcs = 0;
16419        mNewNumAServiceProcs = 0;
16420
16421        final int emptyProcessLimit;
16422        final int cachedProcessLimit;
16423        if (mProcessLimit <= 0) {
16424            emptyProcessLimit = cachedProcessLimit = 0;
16425        } else if (mProcessLimit == 1) {
16426            emptyProcessLimit = 1;
16427            cachedProcessLimit = 0;
16428        } else {
16429            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16430            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16431        }
16432
16433        // Let's determine how many processes we have running vs.
16434        // how many slots we have for background processes; we may want
16435        // to put multiple processes in a slot of there are enough of
16436        // them.
16437        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16438                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16439        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16440        if (numEmptyProcs > cachedProcessLimit) {
16441            // If there are more empty processes than our limit on cached
16442            // processes, then use the cached process limit for the factor.
16443            // This ensures that the really old empty processes get pushed
16444            // down to the bottom, so if we are running low on memory we will
16445            // have a better chance at keeping around more cached processes
16446            // instead of a gazillion empty processes.
16447            numEmptyProcs = cachedProcessLimit;
16448        }
16449        int emptyFactor = numEmptyProcs/numSlots;
16450        if (emptyFactor < 1) emptyFactor = 1;
16451        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16452        if (cachedFactor < 1) cachedFactor = 1;
16453        int stepCached = 0;
16454        int stepEmpty = 0;
16455        int numCached = 0;
16456        int numEmpty = 0;
16457        int numTrimming = 0;
16458
16459        mNumNonCachedProcs = 0;
16460        mNumCachedHiddenProcs = 0;
16461
16462        // First update the OOM adjustment for each of the
16463        // application processes based on their current state.
16464        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16465        int nextCachedAdj = curCachedAdj+1;
16466        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16467        int nextEmptyAdj = curEmptyAdj+2;
16468        for (int i=N-1; i>=0; i--) {
16469            ProcessRecord app = mLruProcesses.get(i);
16470            if (!app.killedByAm && app.thread != null) {
16471                app.procStateChanged = false;
16472                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16473
16474                // If we haven't yet assigned the final cached adj
16475                // to the process, do that now.
16476                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16477                    switch (app.curProcState) {
16478                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16479                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16480                            // This process is a cached process holding activities...
16481                            // assign it the next cached value for that type, and then
16482                            // step that cached level.
16483                            app.curRawAdj = curCachedAdj;
16484                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16485                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16486                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16487                                    + ")");
16488                            if (curCachedAdj != nextCachedAdj) {
16489                                stepCached++;
16490                                if (stepCached >= cachedFactor) {
16491                                    stepCached = 0;
16492                                    curCachedAdj = nextCachedAdj;
16493                                    nextCachedAdj += 2;
16494                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16495                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16496                                    }
16497                                }
16498                            }
16499                            break;
16500                        default:
16501                            // For everything else, assign next empty cached process
16502                            // level and bump that up.  Note that this means that
16503                            // long-running services that have dropped down to the
16504                            // cached level will be treated as empty (since their process
16505                            // state is still as a service), which is what we want.
16506                            app.curRawAdj = curEmptyAdj;
16507                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16508                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16509                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16510                                    + ")");
16511                            if (curEmptyAdj != nextEmptyAdj) {
16512                                stepEmpty++;
16513                                if (stepEmpty >= emptyFactor) {
16514                                    stepEmpty = 0;
16515                                    curEmptyAdj = nextEmptyAdj;
16516                                    nextEmptyAdj += 2;
16517                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16518                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16519                                    }
16520                                }
16521                            }
16522                            break;
16523                    }
16524                }
16525
16526                applyOomAdjLocked(app, TOP_APP, true, now);
16527
16528                // Count the number of process types.
16529                switch (app.curProcState) {
16530                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16531                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16532                        mNumCachedHiddenProcs++;
16533                        numCached++;
16534                        if (numCached > cachedProcessLimit) {
16535                            killUnneededProcessLocked(app, "cached #" + numCached);
16536                        }
16537                        break;
16538                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16539                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16540                                && app.lastActivityTime < oldTime) {
16541                            killUnneededProcessLocked(app, "empty for "
16542                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16543                                    / 1000) + "s");
16544                        } else {
16545                            numEmpty++;
16546                            if (numEmpty > emptyProcessLimit) {
16547                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16548                            }
16549                        }
16550                        break;
16551                    default:
16552                        mNumNonCachedProcs++;
16553                        break;
16554                }
16555
16556                if (app.isolated && app.services.size() <= 0) {
16557                    // If this is an isolated process, and there are no
16558                    // services running in it, then the process is no longer
16559                    // needed.  We agressively kill these because we can by
16560                    // definition not re-use the same process again, and it is
16561                    // good to avoid having whatever code was running in them
16562                    // left sitting around after no longer needed.
16563                    killUnneededProcessLocked(app, "isolated not needed");
16564                }
16565
16566                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16567                        && !app.killedByAm) {
16568                    numTrimming++;
16569                }
16570            }
16571        }
16572
16573        mNumServiceProcs = mNewNumServiceProcs;
16574
16575        // Now determine the memory trimming level of background processes.
16576        // Unfortunately we need to start at the back of the list to do this
16577        // properly.  We only do this if the number of background apps we
16578        // are managing to keep around is less than half the maximum we desire;
16579        // if we are keeping a good number around, we'll let them use whatever
16580        // memory they want.
16581        final int numCachedAndEmpty = numCached + numEmpty;
16582        int memFactor;
16583        if (numCached <= ProcessList.TRIM_CACHED_APPS
16584                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16585            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16586                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16587            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16588                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16589            } else {
16590                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16591            }
16592        } else {
16593            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16594        }
16595        // We always allow the memory level to go up (better).  We only allow it to go
16596        // down if we are in a state where that is allowed, *and* the total number of processes
16597        // has gone down since last time.
16598        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16599                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16600                + " last=" + mLastNumProcesses);
16601        if (memFactor > mLastMemoryLevel) {
16602            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16603                memFactor = mLastMemoryLevel;
16604                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16605            }
16606        }
16607        mLastMemoryLevel = memFactor;
16608        mLastNumProcesses = mLruProcesses.size();
16609        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16610        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16611        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16612            if (mLowRamStartTime == 0) {
16613                mLowRamStartTime = now;
16614            }
16615            int step = 0;
16616            int fgTrimLevel;
16617            switch (memFactor) {
16618                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16619                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16620                    break;
16621                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16622                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16623                    break;
16624                default:
16625                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16626                    break;
16627            }
16628            int factor = numTrimming/3;
16629            int minFactor = 2;
16630            if (mHomeProcess != null) minFactor++;
16631            if (mPreviousProcess != null) minFactor++;
16632            if (factor < minFactor) factor = minFactor;
16633            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16634            for (int i=N-1; i>=0; i--) {
16635                ProcessRecord app = mLruProcesses.get(i);
16636                if (allChanged || app.procStateChanged) {
16637                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16638                    app.procStateChanged = false;
16639                }
16640                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16641                        && !app.killedByAm) {
16642                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16643                        try {
16644                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16645                                    "Trimming memory of " + app.processName
16646                                    + " to " + curLevel);
16647                            app.thread.scheduleTrimMemory(curLevel);
16648                        } catch (RemoteException e) {
16649                        }
16650                        if (false) {
16651                            // For now we won't do this; our memory trimming seems
16652                            // to be good enough at this point that destroying
16653                            // activities causes more harm than good.
16654                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16655                                    && app != mHomeProcess && app != mPreviousProcess) {
16656                                // Need to do this on its own message because the stack may not
16657                                // be in a consistent state at this point.
16658                                // For these apps we will also finish their activities
16659                                // to help them free memory.
16660                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16661                            }
16662                        }
16663                    }
16664                    app.trimMemoryLevel = curLevel;
16665                    step++;
16666                    if (step >= factor) {
16667                        step = 0;
16668                        switch (curLevel) {
16669                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16670                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16671                                break;
16672                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16673                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16674                                break;
16675                        }
16676                    }
16677                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16678                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16679                            && app.thread != null) {
16680                        try {
16681                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16682                                    "Trimming memory of heavy-weight " + app.processName
16683                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16684                            app.thread.scheduleTrimMemory(
16685                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16686                        } catch (RemoteException e) {
16687                        }
16688                    }
16689                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16690                } else {
16691                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16692                            || app.systemNoUi) && app.pendingUiClean) {
16693                        // If this application is now in the background and it
16694                        // had done UI, then give it the special trim level to
16695                        // have it free UI resources.
16696                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16697                        if (app.trimMemoryLevel < level && app.thread != null) {
16698                            try {
16699                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16700                                        "Trimming memory of bg-ui " + app.processName
16701                                        + " to " + level);
16702                                app.thread.scheduleTrimMemory(level);
16703                            } catch (RemoteException e) {
16704                            }
16705                        }
16706                        app.pendingUiClean = false;
16707                    }
16708                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16709                        try {
16710                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16711                                    "Trimming memory of fg " + app.processName
16712                                    + " to " + fgTrimLevel);
16713                            app.thread.scheduleTrimMemory(fgTrimLevel);
16714                        } catch (RemoteException e) {
16715                        }
16716                    }
16717                    app.trimMemoryLevel = fgTrimLevel;
16718                }
16719            }
16720        } else {
16721            if (mLowRamStartTime != 0) {
16722                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16723                mLowRamStartTime = 0;
16724            }
16725            for (int i=N-1; i>=0; i--) {
16726                ProcessRecord app = mLruProcesses.get(i);
16727                if (allChanged || app.procStateChanged) {
16728                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16729                    app.procStateChanged = false;
16730                }
16731                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16732                        || app.systemNoUi) && app.pendingUiClean) {
16733                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16734                            && app.thread != null) {
16735                        try {
16736                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16737                                    "Trimming memory of ui hidden " + app.processName
16738                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16739                            app.thread.scheduleTrimMemory(
16740                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16741                        } catch (RemoteException e) {
16742                        }
16743                    }
16744                    app.pendingUiClean = false;
16745                }
16746                app.trimMemoryLevel = 0;
16747            }
16748        }
16749
16750        if (mAlwaysFinishActivities) {
16751            // Need to do this on its own message because the stack may not
16752            // be in a consistent state at this point.
16753            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16754        }
16755
16756        if (allChanged) {
16757            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16758        }
16759
16760        if (mProcessStats.shouldWriteNowLocked(now)) {
16761            mHandler.post(new Runnable() {
16762                @Override public void run() {
16763                    synchronized (ActivityManagerService.this) {
16764                        mProcessStats.writeStateAsyncLocked();
16765                    }
16766                }
16767            });
16768        }
16769
16770        if (DEBUG_OOM_ADJ) {
16771            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16772        }
16773    }
16774
16775    final void trimApplications() {
16776        synchronized (this) {
16777            int i;
16778
16779            // First remove any unused application processes whose package
16780            // has been removed.
16781            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16782                final ProcessRecord app = mRemovedProcesses.get(i);
16783                if (app.activities.size() == 0
16784                        && app.curReceiver == null && app.services.size() == 0) {
16785                    Slog.i(
16786                        TAG, "Exiting empty application process "
16787                        + app.processName + " ("
16788                        + (app.thread != null ? app.thread.asBinder() : null)
16789                        + ")\n");
16790                    if (app.pid > 0 && app.pid != MY_PID) {
16791                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16792                                app.processName, app.setAdj, "empty");
16793                        app.killedByAm = true;
16794                        Process.killProcessQuiet(app.pid);
16795                        Process.killProcessGroup(app.info.uid, app.pid);
16796                    } else {
16797                        try {
16798                            app.thread.scheduleExit();
16799                        } catch (Exception e) {
16800                            // Ignore exceptions.
16801                        }
16802                    }
16803                    cleanUpApplicationRecordLocked(app, false, true, -1);
16804                    mRemovedProcesses.remove(i);
16805
16806                    if (app.persistent) {
16807                        addAppLocked(app.info, false, null /* ABI override */);
16808                    }
16809                }
16810            }
16811
16812            // Now update the oom adj for all processes.
16813            updateOomAdjLocked();
16814        }
16815    }
16816
16817    /** This method sends the specified signal to each of the persistent apps */
16818    public void signalPersistentProcesses(int sig) throws RemoteException {
16819        if (sig != Process.SIGNAL_USR1) {
16820            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16821        }
16822
16823        synchronized (this) {
16824            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16825                    != PackageManager.PERMISSION_GRANTED) {
16826                throw new SecurityException("Requires permission "
16827                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16828            }
16829
16830            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16831                ProcessRecord r = mLruProcesses.get(i);
16832                if (r.thread != null && r.persistent) {
16833                    Process.sendSignal(r.pid, sig);
16834                }
16835            }
16836        }
16837    }
16838
16839    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16840        if (proc == null || proc == mProfileProc) {
16841            proc = mProfileProc;
16842            path = mProfileFile;
16843            profileType = mProfileType;
16844            clearProfilerLocked();
16845        }
16846        if (proc == null) {
16847            return;
16848        }
16849        try {
16850            proc.thread.profilerControl(false, path, null, profileType);
16851        } catch (RemoteException e) {
16852            throw new IllegalStateException("Process disappeared");
16853        }
16854    }
16855
16856    private void clearProfilerLocked() {
16857        if (mProfileFd != null) {
16858            try {
16859                mProfileFd.close();
16860            } catch (IOException e) {
16861            }
16862        }
16863        mProfileApp = null;
16864        mProfileProc = null;
16865        mProfileFile = null;
16866        mProfileType = 0;
16867        mAutoStopProfiler = false;
16868    }
16869
16870    public boolean profileControl(String process, int userId, boolean start,
16871            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16872
16873        try {
16874            synchronized (this) {
16875                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16876                // its own permission.
16877                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16878                        != PackageManager.PERMISSION_GRANTED) {
16879                    throw new SecurityException("Requires permission "
16880                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16881                }
16882
16883                if (start && fd == null) {
16884                    throw new IllegalArgumentException("null fd");
16885                }
16886
16887                ProcessRecord proc = null;
16888                if (process != null) {
16889                    proc = findProcessLocked(process, userId, "profileControl");
16890                }
16891
16892                if (start && (proc == null || proc.thread == null)) {
16893                    throw new IllegalArgumentException("Unknown process: " + process);
16894                }
16895
16896                if (start) {
16897                    stopProfilerLocked(null, null, 0);
16898                    setProfileApp(proc.info, proc.processName, path, fd, false);
16899                    mProfileProc = proc;
16900                    mProfileType = profileType;
16901                    try {
16902                        fd = fd.dup();
16903                    } catch (IOException e) {
16904                        fd = null;
16905                    }
16906                    proc.thread.profilerControl(start, path, fd, profileType);
16907                    fd = null;
16908                    mProfileFd = null;
16909                } else {
16910                    stopProfilerLocked(proc, path, profileType);
16911                    if (fd != null) {
16912                        try {
16913                            fd.close();
16914                        } catch (IOException e) {
16915                        }
16916                    }
16917                }
16918
16919                return true;
16920            }
16921        } catch (RemoteException e) {
16922            throw new IllegalStateException("Process disappeared");
16923        } finally {
16924            if (fd != null) {
16925                try {
16926                    fd.close();
16927                } catch (IOException e) {
16928                }
16929            }
16930        }
16931    }
16932
16933    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16934        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16935                userId, true, ALLOW_FULL_ONLY, callName, null);
16936        ProcessRecord proc = null;
16937        try {
16938            int pid = Integer.parseInt(process);
16939            synchronized (mPidsSelfLocked) {
16940                proc = mPidsSelfLocked.get(pid);
16941            }
16942        } catch (NumberFormatException e) {
16943        }
16944
16945        if (proc == null) {
16946            ArrayMap<String, SparseArray<ProcessRecord>> all
16947                    = mProcessNames.getMap();
16948            SparseArray<ProcessRecord> procs = all.get(process);
16949            if (procs != null && procs.size() > 0) {
16950                proc = procs.valueAt(0);
16951                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16952                    for (int i=1; i<procs.size(); i++) {
16953                        ProcessRecord thisProc = procs.valueAt(i);
16954                        if (thisProc.userId == userId) {
16955                            proc = thisProc;
16956                            break;
16957                        }
16958                    }
16959                }
16960            }
16961        }
16962
16963        return proc;
16964    }
16965
16966    public boolean dumpHeap(String process, int userId, boolean managed,
16967            String path, ParcelFileDescriptor fd) throws RemoteException {
16968
16969        try {
16970            synchronized (this) {
16971                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16972                // its own permission (same as profileControl).
16973                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16974                        != PackageManager.PERMISSION_GRANTED) {
16975                    throw new SecurityException("Requires permission "
16976                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16977                }
16978
16979                if (fd == null) {
16980                    throw new IllegalArgumentException("null fd");
16981                }
16982
16983                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16984                if (proc == null || proc.thread == null) {
16985                    throw new IllegalArgumentException("Unknown process: " + process);
16986                }
16987
16988                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16989                if (!isDebuggable) {
16990                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16991                        throw new SecurityException("Process not debuggable: " + proc);
16992                    }
16993                }
16994
16995                proc.thread.dumpHeap(managed, path, fd);
16996                fd = null;
16997                return true;
16998            }
16999        } catch (RemoteException e) {
17000            throw new IllegalStateException("Process disappeared");
17001        } finally {
17002            if (fd != null) {
17003                try {
17004                    fd.close();
17005                } catch (IOException e) {
17006                }
17007            }
17008        }
17009    }
17010
17011    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17012    public void monitor() {
17013        synchronized (this) { }
17014    }
17015
17016    void onCoreSettingsChange(Bundle settings) {
17017        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17018            ProcessRecord processRecord = mLruProcesses.get(i);
17019            try {
17020                if (processRecord.thread != null) {
17021                    processRecord.thread.setCoreSettings(settings);
17022                }
17023            } catch (RemoteException re) {
17024                /* ignore */
17025            }
17026        }
17027    }
17028
17029    // Multi-user methods
17030
17031    /**
17032     * Start user, if its not already running, but don't bring it to foreground.
17033     */
17034    @Override
17035    public boolean startUserInBackground(final int userId) {
17036        return startUser(userId, /* foreground */ false);
17037    }
17038
17039    /**
17040     * Refreshes the list of users related to the current user when either a
17041     * user switch happens or when a new related user is started in the
17042     * background.
17043     */
17044    private void updateCurrentProfileIdsLocked() {
17045        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17046                mCurrentUserId, false /* enabledOnly */);
17047        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17048        for (int i = 0; i < currentProfileIds.length; i++) {
17049            currentProfileIds[i] = profiles.get(i).id;
17050        }
17051        mCurrentProfileIds = currentProfileIds;
17052
17053        synchronized (mUserProfileGroupIdsSelfLocked) {
17054            mUserProfileGroupIdsSelfLocked.clear();
17055            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17056            for (int i = 0; i < users.size(); i++) {
17057                UserInfo user = users.get(i);
17058                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17059                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17060                }
17061            }
17062        }
17063    }
17064
17065    private Set getProfileIdsLocked(int userId) {
17066        Set userIds = new HashSet<Integer>();
17067        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17068                userId, false /* enabledOnly */);
17069        for (UserInfo user : profiles) {
17070            userIds.add(Integer.valueOf(user.id));
17071        }
17072        return userIds;
17073    }
17074
17075    @Override
17076    public boolean switchUser(final int userId) {
17077        return startUser(userId, /* foregound */ true);
17078    }
17079
17080    private boolean startUser(final int userId, boolean foreground) {
17081        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17082                != PackageManager.PERMISSION_GRANTED) {
17083            String msg = "Permission Denial: switchUser() from pid="
17084                    + Binder.getCallingPid()
17085                    + ", uid=" + Binder.getCallingUid()
17086                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17087            Slog.w(TAG, msg);
17088            throw new SecurityException(msg);
17089        }
17090
17091        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17092
17093        final long ident = Binder.clearCallingIdentity();
17094        try {
17095            synchronized (this) {
17096                final int oldUserId = mCurrentUserId;
17097                if (oldUserId == userId) {
17098                    return true;
17099                }
17100
17101                mStackSupervisor.setLockTaskModeLocked(null, false);
17102
17103                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17104                if (userInfo == null) {
17105                    Slog.w(TAG, "No user info for user #" + userId);
17106                    return false;
17107                }
17108
17109                if (foreground) {
17110                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17111                            R.anim.screen_user_enter);
17112                }
17113
17114                boolean needStart = false;
17115
17116                // If the user we are switching to is not currently started, then
17117                // we need to start it now.
17118                if (mStartedUsers.get(userId) == null) {
17119                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17120                    updateStartedUserArrayLocked();
17121                    needStart = true;
17122                }
17123
17124                final Integer userIdInt = Integer.valueOf(userId);
17125                mUserLru.remove(userIdInt);
17126                mUserLru.add(userIdInt);
17127
17128                if (foreground) {
17129                    mCurrentUserId = userId;
17130                    updateCurrentProfileIdsLocked();
17131                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17132                    // Once the internal notion of the active user has switched, we lock the device
17133                    // with the option to show the user switcher on the keyguard.
17134                    mWindowManager.lockNow(null);
17135                } else {
17136                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17137                    updateCurrentProfileIdsLocked();
17138                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17139                    mUserLru.remove(currentUserIdInt);
17140                    mUserLru.add(currentUserIdInt);
17141                }
17142
17143                final UserStartedState uss = mStartedUsers.get(userId);
17144
17145                // Make sure user is in the started state.  If it is currently
17146                // stopping, we need to knock that off.
17147                if (uss.mState == UserStartedState.STATE_STOPPING) {
17148                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17149                    // so we can just fairly silently bring the user back from
17150                    // the almost-dead.
17151                    uss.mState = UserStartedState.STATE_RUNNING;
17152                    updateStartedUserArrayLocked();
17153                    needStart = true;
17154                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17155                    // This means ACTION_SHUTDOWN has been sent, so we will
17156                    // need to treat this as a new boot of the user.
17157                    uss.mState = UserStartedState.STATE_BOOTING;
17158                    updateStartedUserArrayLocked();
17159                    needStart = true;
17160                }
17161
17162                if (uss.mState == UserStartedState.STATE_BOOTING) {
17163                    // Booting up a new user, need to tell system services about it.
17164                    // Note that this is on the same handler as scheduling of broadcasts,
17165                    // which is important because it needs to go first.
17166                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17167                }
17168
17169                if (foreground) {
17170                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17171                            oldUserId));
17172                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17173                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17174                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17175                            oldUserId, userId, uss));
17176                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17177                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17178                }
17179
17180                if (needStart) {
17181                    // Send USER_STARTED broadcast
17182                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17183                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17184                            | Intent.FLAG_RECEIVER_FOREGROUND);
17185                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17186                    broadcastIntentLocked(null, null, intent,
17187                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17188                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17189                }
17190
17191                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17192                    if (userId != UserHandle.USER_OWNER) {
17193                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17194                        final ArrayList<ComponentName> doneReceivers
17195                                = new ArrayList<ComponentName>();
17196                        deliverPreBootCompleted(null, doneReceivers, userId);
17197
17198                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17199                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17200                        broadcastIntentLocked(null, null, intent, null,
17201                                new IIntentReceiver.Stub() {
17202                                    public void performReceive(Intent intent, int resultCode,
17203                                            String data, Bundle extras, boolean ordered,
17204                                            boolean sticky, int sendingUser) {
17205                                        userInitialized(uss, userId);
17206                                    }
17207                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17208                                true, false, MY_PID, Process.SYSTEM_UID,
17209                                userId);
17210                        uss.initializing = true;
17211                    } else {
17212                        getUserManagerLocked().makeInitialized(userInfo.id);
17213                    }
17214                }
17215
17216                if (foreground) {
17217                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17218                    if (homeInFront) {
17219                        startHomeActivityLocked(userId);
17220                    } else {
17221                        mStackSupervisor.resumeTopActivitiesLocked();
17222                    }
17223                    EventLogTags.writeAmSwitchUser(userId);
17224                    getUserManagerLocked().userForeground(userId);
17225                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17226                } else {
17227                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17228                }
17229
17230                if (needStart) {
17231                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17232                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17233                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17234                    broadcastIntentLocked(null, null, intent,
17235                            null, new IIntentReceiver.Stub() {
17236                                @Override
17237                                public void performReceive(Intent intent, int resultCode, String data,
17238                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17239                                        throws RemoteException {
17240                                }
17241                            }, 0, null, null,
17242                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17243                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17244                }
17245            }
17246        } finally {
17247            Binder.restoreCallingIdentity(ident);
17248        }
17249
17250        return true;
17251    }
17252
17253    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17254        long ident = Binder.clearCallingIdentity();
17255        try {
17256            Intent intent;
17257            if (oldUserId >= 0) {
17258                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17259                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17260                int count = profiles.size();
17261                for (int i = 0; i < count; i++) {
17262                    int profileUserId = profiles.get(i).id;
17263                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17264                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17265                            | Intent.FLAG_RECEIVER_FOREGROUND);
17266                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17267                    broadcastIntentLocked(null, null, intent,
17268                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17269                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17270                }
17271            }
17272            if (newUserId >= 0) {
17273                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17274                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17275                int count = profiles.size();
17276                for (int i = 0; i < count; i++) {
17277                    int profileUserId = profiles.get(i).id;
17278                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17279                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17280                            | Intent.FLAG_RECEIVER_FOREGROUND);
17281                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17282                    broadcastIntentLocked(null, null, intent,
17283                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17284                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17285                }
17286                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17287                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17288                        | Intent.FLAG_RECEIVER_FOREGROUND);
17289                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17290                broadcastIntentLocked(null, null, intent,
17291                        null, null, 0, null, null,
17292                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17293                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17294            }
17295        } finally {
17296            Binder.restoreCallingIdentity(ident);
17297        }
17298    }
17299
17300    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17301            final int newUserId) {
17302        final int N = mUserSwitchObservers.beginBroadcast();
17303        if (N > 0) {
17304            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17305                int mCount = 0;
17306                @Override
17307                public void sendResult(Bundle data) throws RemoteException {
17308                    synchronized (ActivityManagerService.this) {
17309                        if (mCurUserSwitchCallback == this) {
17310                            mCount++;
17311                            if (mCount == N) {
17312                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17313                            }
17314                        }
17315                    }
17316                }
17317            };
17318            synchronized (this) {
17319                uss.switching = true;
17320                mCurUserSwitchCallback = callback;
17321            }
17322            for (int i=0; i<N; i++) {
17323                try {
17324                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17325                            newUserId, callback);
17326                } catch (RemoteException e) {
17327                }
17328            }
17329        } else {
17330            synchronized (this) {
17331                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17332            }
17333        }
17334        mUserSwitchObservers.finishBroadcast();
17335    }
17336
17337    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17338        synchronized (this) {
17339            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17340            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17341        }
17342    }
17343
17344    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17345        mCurUserSwitchCallback = null;
17346        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17347        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17348                oldUserId, newUserId, uss));
17349    }
17350
17351    void userInitialized(UserStartedState uss, int newUserId) {
17352        completeSwitchAndInitalize(uss, newUserId, true, false);
17353    }
17354
17355    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17356        completeSwitchAndInitalize(uss, newUserId, false, true);
17357    }
17358
17359    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17360            boolean clearInitializing, boolean clearSwitching) {
17361        boolean unfrozen = false;
17362        synchronized (this) {
17363            if (clearInitializing) {
17364                uss.initializing = false;
17365                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17366            }
17367            if (clearSwitching) {
17368                uss.switching = false;
17369            }
17370            if (!uss.switching && !uss.initializing) {
17371                mWindowManager.stopFreezingScreen();
17372                unfrozen = true;
17373            }
17374        }
17375        if (unfrozen) {
17376            final int N = mUserSwitchObservers.beginBroadcast();
17377            for (int i=0; i<N; i++) {
17378                try {
17379                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17380                } catch (RemoteException e) {
17381                }
17382            }
17383            mUserSwitchObservers.finishBroadcast();
17384        }
17385    }
17386
17387    void scheduleStartProfilesLocked() {
17388        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17389            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17390                    DateUtils.SECOND_IN_MILLIS);
17391        }
17392    }
17393
17394    void startProfilesLocked() {
17395        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17396        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17397                mCurrentUserId, false /* enabledOnly */);
17398        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17399        for (UserInfo user : profiles) {
17400            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17401                    && user.id != mCurrentUserId) {
17402                toStart.add(user);
17403            }
17404        }
17405        final int n = toStart.size();
17406        int i = 0;
17407        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17408            startUserInBackground(toStart.get(i).id);
17409        }
17410        if (i < n) {
17411            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17412        }
17413    }
17414
17415    void finishUserBoot(UserStartedState uss) {
17416        synchronized (this) {
17417            if (uss.mState == UserStartedState.STATE_BOOTING
17418                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17419                uss.mState = UserStartedState.STATE_RUNNING;
17420                final int userId = uss.mHandle.getIdentifier();
17421                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17422                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17423                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17424                broadcastIntentLocked(null, null, intent,
17425                        null, null, 0, null, null,
17426                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17427                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17428            }
17429        }
17430    }
17431
17432    void finishUserSwitch(UserStartedState uss) {
17433        synchronized (this) {
17434            finishUserBoot(uss);
17435
17436            startProfilesLocked();
17437
17438            int num = mUserLru.size();
17439            int i = 0;
17440            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17441                Integer oldUserId = mUserLru.get(i);
17442                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17443                if (oldUss == null) {
17444                    // Shouldn't happen, but be sane if it does.
17445                    mUserLru.remove(i);
17446                    num--;
17447                    continue;
17448                }
17449                if (oldUss.mState == UserStartedState.STATE_STOPPING
17450                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17451                    // This user is already stopping, doesn't count.
17452                    num--;
17453                    i++;
17454                    continue;
17455                }
17456                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17457                    // Owner and current can't be stopped, but count as running.
17458                    i++;
17459                    continue;
17460                }
17461                // This is a user to be stopped.
17462                stopUserLocked(oldUserId, null);
17463                num--;
17464                i++;
17465            }
17466        }
17467    }
17468
17469    @Override
17470    public int stopUser(final int userId, final IStopUserCallback callback) {
17471        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17472                != PackageManager.PERMISSION_GRANTED) {
17473            String msg = "Permission Denial: switchUser() from pid="
17474                    + Binder.getCallingPid()
17475                    + ", uid=" + Binder.getCallingUid()
17476                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17477            Slog.w(TAG, msg);
17478            throw new SecurityException(msg);
17479        }
17480        if (userId <= 0) {
17481            throw new IllegalArgumentException("Can't stop primary user " + userId);
17482        }
17483        synchronized (this) {
17484            return stopUserLocked(userId, callback);
17485        }
17486    }
17487
17488    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17489        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17490        if (mCurrentUserId == userId) {
17491            return ActivityManager.USER_OP_IS_CURRENT;
17492        }
17493
17494        final UserStartedState uss = mStartedUsers.get(userId);
17495        if (uss == null) {
17496            // User is not started, nothing to do...  but we do need to
17497            // callback if requested.
17498            if (callback != null) {
17499                mHandler.post(new Runnable() {
17500                    @Override
17501                    public void run() {
17502                        try {
17503                            callback.userStopped(userId);
17504                        } catch (RemoteException e) {
17505                        }
17506                    }
17507                });
17508            }
17509            return ActivityManager.USER_OP_SUCCESS;
17510        }
17511
17512        if (callback != null) {
17513            uss.mStopCallbacks.add(callback);
17514        }
17515
17516        if (uss.mState != UserStartedState.STATE_STOPPING
17517                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17518            uss.mState = UserStartedState.STATE_STOPPING;
17519            updateStartedUserArrayLocked();
17520
17521            long ident = Binder.clearCallingIdentity();
17522            try {
17523                // We are going to broadcast ACTION_USER_STOPPING and then
17524                // once that is done send a final ACTION_SHUTDOWN and then
17525                // stop the user.
17526                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17527                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17528                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17529                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17530                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17531                // This is the result receiver for the final shutdown broadcast.
17532                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17533                    @Override
17534                    public void performReceive(Intent intent, int resultCode, String data,
17535                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17536                        finishUserStop(uss);
17537                    }
17538                };
17539                // This is the result receiver for the initial stopping broadcast.
17540                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17541                    @Override
17542                    public void performReceive(Intent intent, int resultCode, String data,
17543                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17544                        // On to the next.
17545                        synchronized (ActivityManagerService.this) {
17546                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17547                                // Whoops, we are being started back up.  Abort, abort!
17548                                return;
17549                            }
17550                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17551                        }
17552                        mBatteryStatsService.noteEvent(
17553                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17554                                Integer.toString(userId), userId);
17555                        mSystemServiceManager.stopUser(userId);
17556                        broadcastIntentLocked(null, null, shutdownIntent,
17557                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17558                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17559                    }
17560                };
17561                // Kick things off.
17562                broadcastIntentLocked(null, null, stoppingIntent,
17563                        null, stoppingReceiver, 0, null, null,
17564                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17565                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17566            } finally {
17567                Binder.restoreCallingIdentity(ident);
17568            }
17569        }
17570
17571        return ActivityManager.USER_OP_SUCCESS;
17572    }
17573
17574    void finishUserStop(UserStartedState uss) {
17575        final int userId = uss.mHandle.getIdentifier();
17576        boolean stopped;
17577        ArrayList<IStopUserCallback> callbacks;
17578        synchronized (this) {
17579            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17580            if (mStartedUsers.get(userId) != uss) {
17581                stopped = false;
17582            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17583                stopped = false;
17584            } else {
17585                stopped = true;
17586                // User can no longer run.
17587                mStartedUsers.remove(userId);
17588                mUserLru.remove(Integer.valueOf(userId));
17589                updateStartedUserArrayLocked();
17590
17591                // Clean up all state and processes associated with the user.
17592                // Kill all the processes for the user.
17593                forceStopUserLocked(userId, "finish user");
17594            }
17595        }
17596
17597        for (int i=0; i<callbacks.size(); i++) {
17598            try {
17599                if (stopped) callbacks.get(i).userStopped(userId);
17600                else callbacks.get(i).userStopAborted(userId);
17601            } catch (RemoteException e) {
17602            }
17603        }
17604
17605        if (stopped) {
17606            mSystemServiceManager.cleanupUser(userId);
17607            synchronized (this) {
17608                mStackSupervisor.removeUserLocked(userId);
17609            }
17610        }
17611    }
17612
17613    @Override
17614    public UserInfo getCurrentUser() {
17615        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17616                != PackageManager.PERMISSION_GRANTED) && (
17617                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17618                != PackageManager.PERMISSION_GRANTED)) {
17619            String msg = "Permission Denial: getCurrentUser() from pid="
17620                    + Binder.getCallingPid()
17621                    + ", uid=" + Binder.getCallingUid()
17622                    + " requires " + INTERACT_ACROSS_USERS;
17623            Slog.w(TAG, msg);
17624            throw new SecurityException(msg);
17625        }
17626        synchronized (this) {
17627            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17628        }
17629    }
17630
17631    int getCurrentUserIdLocked() {
17632        return mCurrentUserId;
17633    }
17634
17635    @Override
17636    public boolean isUserRunning(int userId, boolean orStopped) {
17637        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17638                != PackageManager.PERMISSION_GRANTED) {
17639            String msg = "Permission Denial: isUserRunning() from pid="
17640                    + Binder.getCallingPid()
17641                    + ", uid=" + Binder.getCallingUid()
17642                    + " requires " + INTERACT_ACROSS_USERS;
17643            Slog.w(TAG, msg);
17644            throw new SecurityException(msg);
17645        }
17646        synchronized (this) {
17647            return isUserRunningLocked(userId, orStopped);
17648        }
17649    }
17650
17651    boolean isUserRunningLocked(int userId, boolean orStopped) {
17652        UserStartedState state = mStartedUsers.get(userId);
17653        if (state == null) {
17654            return false;
17655        }
17656        if (orStopped) {
17657            return true;
17658        }
17659        return state.mState != UserStartedState.STATE_STOPPING
17660                && state.mState != UserStartedState.STATE_SHUTDOWN;
17661    }
17662
17663    @Override
17664    public int[] getRunningUserIds() {
17665        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17666                != PackageManager.PERMISSION_GRANTED) {
17667            String msg = "Permission Denial: isUserRunning() from pid="
17668                    + Binder.getCallingPid()
17669                    + ", uid=" + Binder.getCallingUid()
17670                    + " requires " + INTERACT_ACROSS_USERS;
17671            Slog.w(TAG, msg);
17672            throw new SecurityException(msg);
17673        }
17674        synchronized (this) {
17675            return mStartedUserArray;
17676        }
17677    }
17678
17679    private void updateStartedUserArrayLocked() {
17680        int num = 0;
17681        for (int i=0; i<mStartedUsers.size();  i++) {
17682            UserStartedState uss = mStartedUsers.valueAt(i);
17683            // This list does not include stopping users.
17684            if (uss.mState != UserStartedState.STATE_STOPPING
17685                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17686                num++;
17687            }
17688        }
17689        mStartedUserArray = new int[num];
17690        num = 0;
17691        for (int i=0; i<mStartedUsers.size();  i++) {
17692            UserStartedState uss = mStartedUsers.valueAt(i);
17693            if (uss.mState != UserStartedState.STATE_STOPPING
17694                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17695                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17696                num++;
17697            }
17698        }
17699    }
17700
17701    @Override
17702    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17703        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17704                != PackageManager.PERMISSION_GRANTED) {
17705            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17706                    + Binder.getCallingPid()
17707                    + ", uid=" + Binder.getCallingUid()
17708                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17709            Slog.w(TAG, msg);
17710            throw new SecurityException(msg);
17711        }
17712
17713        mUserSwitchObservers.register(observer);
17714    }
17715
17716    @Override
17717    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17718        mUserSwitchObservers.unregister(observer);
17719    }
17720
17721    private boolean userExists(int userId) {
17722        if (userId == 0) {
17723            return true;
17724        }
17725        UserManagerService ums = getUserManagerLocked();
17726        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17727    }
17728
17729    int[] getUsersLocked() {
17730        UserManagerService ums = getUserManagerLocked();
17731        return ums != null ? ums.getUserIds() : new int[] { 0 };
17732    }
17733
17734    UserManagerService getUserManagerLocked() {
17735        if (mUserManager == null) {
17736            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17737            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17738        }
17739        return mUserManager;
17740    }
17741
17742    private int applyUserId(int uid, int userId) {
17743        return UserHandle.getUid(userId, uid);
17744    }
17745
17746    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17747        if (info == null) return null;
17748        ApplicationInfo newInfo = new ApplicationInfo(info);
17749        newInfo.uid = applyUserId(info.uid, userId);
17750        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17751                + info.packageName;
17752        return newInfo;
17753    }
17754
17755    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17756        if (aInfo == null
17757                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17758            return aInfo;
17759        }
17760
17761        ActivityInfo info = new ActivityInfo(aInfo);
17762        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17763        return info;
17764    }
17765
17766    private final class LocalService extends ActivityManagerInternal {
17767        @Override
17768        public void goingToSleep() {
17769            ActivityManagerService.this.goingToSleep();
17770        }
17771
17772        @Override
17773        public void wakingUp() {
17774            ActivityManagerService.this.wakingUp();
17775        }
17776    }
17777
17778    /**
17779     * An implementation of IAppTask, that allows an app to manage its own tasks via
17780     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17781     * only the process that calls getAppTasks() can call the AppTask methods.
17782     */
17783    class AppTaskImpl extends IAppTask.Stub {
17784        private int mTaskId;
17785        private int mCallingUid;
17786
17787        public AppTaskImpl(int taskId, int callingUid) {
17788            mTaskId = taskId;
17789            mCallingUid = callingUid;
17790        }
17791
17792        @Override
17793        public void finishAndRemoveTask() {
17794            // Ensure that we are called from the same process that created this AppTask
17795            if (mCallingUid != Binder.getCallingUid()) {
17796                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17797                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17798                return;
17799            }
17800
17801            synchronized (ActivityManagerService.this) {
17802                long origId = Binder.clearCallingIdentity();
17803                try {
17804                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17805                    if (tr != null) {
17806                        // Only kill the process if we are not a new document
17807                        int flags = tr.getBaseIntent().getFlags();
17808                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17809                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17810                        removeTaskByIdLocked(mTaskId,
17811                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17812                    }
17813                } finally {
17814                    Binder.restoreCallingIdentity(origId);
17815                }
17816            }
17817        }
17818
17819        @Override
17820        public ActivityManager.RecentTaskInfo getTaskInfo() {
17821            // Ensure that we are called from the same process that created this AppTask
17822            if (mCallingUid != Binder.getCallingUid()) {
17823                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17824                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17825                return null;
17826            }
17827
17828            synchronized (ActivityManagerService.this) {
17829                long origId = Binder.clearCallingIdentity();
17830                try {
17831                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17832                    if (tr != null) {
17833                        return createRecentTaskInfoFromTaskRecord(tr);
17834                    }
17835                } finally {
17836                    Binder.restoreCallingIdentity(origId);
17837                }
17838                return null;
17839            }
17840        }
17841    }
17842}
17843